vtk-m2/vtkmstd/is_trivial.h
Kenneth Moreland 4a7aae86f9 Allow Variant to be trivial
Although `vtkm::internal::Variant` respected the trivially copyable
attribute of the types it contains, it was never totally trivial (i.e.
`std::is_trivial<Variant<...>>` was never true). The reason was that
`Variant` was initializing its `Index` parameter to signify that it was
not initialized. However, the fact that `Index` was initialized meant
that it was not trivially constructed.

Now, `Variant` type checks its types to see if they are all trivially
constructible. If so, it makes itself trivially constructible.

This means that `Index` may or may not be valid if `Variant` is
constructed without an argument. This in turn means that the result of
`Variant::IsValid` becomes undefined. That should be OK in practice.
`Index` will "point" to an uninitialized object, but that object is
trivially constructed anyway. However, that could cause problems if
developers used `IsValid` to determine if something is selected.
2020-09-22 16:22:37 -06:00

86 lines
3.4 KiB
C++

//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#ifndef vtk_m_std_is_trivial_h
#define vtk_m_std_is_trivial_h
#include <vtkm/StaticAssert.h>
#include <type_traits>
#if defined(VTKM_USING_GLIBCXX_4)
namespace vtkmstd
{
// GCC 4.8 and 4.9 standard library does not support std::is_trivially_copyable.
// There is no relyable way to get this information (since it has to come special from
// the compiler). For our purposes, we will report as nothing being trivially copyable,
// which causes us to call the constructors with everything. This should be fine unless
// some other part of the compiler is trying to check for trivial copies (perhaps nvcc
// on top of GCC 4.8).
template <typename>
struct is_trivially_copyable : std::false_type
{
};
// I haven't tried the other forms of is_trivial, but let's just assume they don't
// work as expected.
template <typename...>
struct is_trivially_constructible : std::false_type
{
};
template <typename>
struct is_trivially_destructible : std::false_type
{
};
template <typename>
struct is_trivial : std::false_type
{
};
// A common exception to reporting nothing as trivially copyable is assertions that
// a class is trivially copyable. If we have code that _only_ works with trivially
// copyable classes, we don't want to report nothing as trivially copyably, because
// that will error out for everything. For this case, we define the macro
// `VTKM_IS_TRIVIALLY_COPYABLE`, which will always pass on compilers that don't
// support is_trivially_copyable, but will do the correct check on compilers that
// do support it.
#define VTKM_IS_TRIVIALLY_COPYABLE(type) VTKM_STATIC_ASSERT(true)
#define VTKM_IS_TRIVIALLY_CONSTRUCTIBLE(...) VTKM_STATIC_ASSERT(true)
#define VTKM_IS_TRIVIALLY_DESTRUCTIBLE(...) VTKM_STATIC_ASSERT(true)
#define VTKM_IS_TRIVIAL(type) VTKM_STATIC_ASSERT(true)
} // namespace vtkmstd
#else // NOT VTKM_USING_GLIBCXX_4
namespace vtkmstd
{
using std::is_trivial;
using std::is_trivially_constructible;
using std::is_trivially_copyable;
using std::is_trivially_destructible;
#define VTKM_IS_TRIVIALLY_COPYABLE(type) \
VTKM_STATIC_ASSERT_MSG(::vtkmstd::is_trivially_copyable<type>::value, \
"Type must be trivially copyable to be used here.")
#define VTKM_IS_TRIVIALLY_CONSTRUCTIBLE(...) \
VTKM_STATIC_ASSERT_MSG(::vtkmstd::is_trivially_constructible<__VA_ARGS__>::value, \
"Type must be trivially constructible to be used here.")
#define VTKM_IS_TRIVIALLY_DESTRUCTIBLE(...) \
VTKM_STATIC_ASSERT_MSG(::vtkmstd::is_trivially_destructible<__VA_ARGS__>::value, \
"Type must be trivially constructible to be used here.")
#define VTKM_IS_TRIVIAL(type) \
VTKM_STATIC_ASSERT_MSG(::vtkmstd::is_trivial<type>::value, \
"Type must be trivial to be used here.")
} // namespace vtkmstd
#endif
#endif //vtk_m_std_is_trivial_h