mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-10-05 01:49:02 +00:00
Add porting layer for future std features
Currently, VTK-m is using C++11. However, it is often useful to use features in the `std` namespace that are defined for C++14 or later. We can provide our own versions (sometimes), but it is preferable to use the version provided by the compiler if available. There were already some examples of defining portable versions of C++14 and C++17 classes in a `vtkmstd` namespace, but these were sprinkled around the source code. There is now a top level `vtkmstd` directory and in it are header files that provide portable versions of these future C++ classes. In each case, preprocessor macros are used to select which version of the class to use.
This commit is contained in:
parent
56636afc7a
commit
5773ea3e13
@ -202,6 +202,7 @@ check_type_size("long long" VTKm_SIZE_LONG_LONG BUILTIN_TYPES_ONLY)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Add subdirectories
|
||||
add_subdirectory(vtkmstd)
|
||||
add_subdirectory(vtkm)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
14
docs/changelog/std_porting_headers.md
Normal file
14
docs/changelog/std_porting_headers.md
Normal file
@ -0,0 +1,14 @@
|
||||
# Porting layer for future std features
|
||||
|
||||
Currently, VTK-m is using C++11. However, it is often useful to use
|
||||
features in the `std` namespace that are defined for C++14 or later. We can
|
||||
provide our own versions (sometimes), but it is preferable to use the
|
||||
version provided by the compiler if available.
|
||||
|
||||
There were already some examples of defining portable versions of C++14 and
|
||||
C++17 classes in a `vtkmstd` namespace, but these were sprinkled around the
|
||||
source code.
|
||||
|
||||
There is now a top level `vtkmstd` directory and in it are header files
|
||||
that provide portable versions of these future C++ classes. In each case,
|
||||
preprocessor macros are used to select which version of the class to use.
|
@ -15,30 +15,7 @@
|
||||
|
||||
#include <vtkm/internal/ArrayPortalHelpers.h>
|
||||
|
||||
namespace vtkmstd
|
||||
{
|
||||
/// Implementation of std::void_t (C++17):
|
||||
/// Allows for specialization of class templates based on members of template
|
||||
/// parameters.
|
||||
#if defined(VTKM_GCC) && (__GNUC__ < 5)
|
||||
// Due to a defect in the wording (CWG 1558) unused parameters in alias templates
|
||||
// were not guaranteed to ensure SFINAE, and therefore would consider everything
|
||||
// to match the 'true' side. For VTK-m the only known compiler that implemented
|
||||
// this defect is GCC < 5.
|
||||
template <class... T>
|
||||
struct void_pack
|
||||
{
|
||||
using type = void;
|
||||
};
|
||||
template <class... T>
|
||||
using void_t = typename void_pack<T...>::type;
|
||||
#else
|
||||
template <typename...>
|
||||
using void_t = void;
|
||||
#endif
|
||||
|
||||
|
||||
} // end namespace vtkmstd
|
||||
#include <vtkmstd/void_t.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
|
@ -15,67 +15,8 @@
|
||||
#include <vtkm/Deprecated.h>
|
||||
#include <vtkm/List.h>
|
||||
|
||||
#if defined(VTKM_USING_GLIBCXX_4)
|
||||
// It would make sense to put this in its own header file, but it is hard to imagine needing
|
||||
// aligned_union anywhere else.
|
||||
#include <algorithm>
|
||||
namespace vtkmstd
|
||||
{
|
||||
|
||||
template <std::size_t... Xs>
|
||||
struct max_size;
|
||||
template <std::size_t X>
|
||||
struct max_size<X>
|
||||
{
|
||||
static constexpr std::size_t value = X;
|
||||
};
|
||||
template <std::size_t X0, std::size_t... Xs>
|
||||
struct max_size<X0, Xs...>
|
||||
{
|
||||
static constexpr std::size_t other_value = max_size<Xs...>::value;
|
||||
static constexpr std::size_t value = (other_value > X0) ? other_value : X0;
|
||||
};
|
||||
|
||||
// This is to get around an apparent bug in GCC 4.8 where alianas(x) does not
|
||||
// seem to work when x is a constexpr. See
|
||||
// https://stackoverflow.com/questions/29879609/g-complains-constexpr-function-is-not-a-constant-expression
|
||||
template <std::size_t Alignment, std::size_t Size>
|
||||
struct aligned_data_block
|
||||
{
|
||||
alignas(Alignment) char _s[Size];
|
||||
};
|
||||
|
||||
template <std::size_t Len, class... Types>
|
||||
struct aligned_union
|
||||
{
|
||||
static constexpr std::size_t alignment_value = vtkmstd::max_size<alignof(Types)...>::value;
|
||||
|
||||
using type =
|
||||
vtkmstd::aligned_data_block<alignment_value, vtkmstd::max_size<Len, sizeof(Types)...>::value>;
|
||||
};
|
||||
|
||||
// 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
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace vtkmstd
|
||||
|
||||
#else // NOT VTKM_USING_GLIBCXX_4
|
||||
namespace vtkmstd
|
||||
{
|
||||
|
||||
using std::aligned_union;
|
||||
using std::is_trivially_copyable;
|
||||
|
||||
} // namespace vtkmstd
|
||||
#endif
|
||||
#include <vtkmstd/aligned_union.h>
|
||||
#include <vtkmstd/is_trivially_copyable.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
|
17
vtkmstd/CMakeLists.txt
Normal file
17
vtkmstd/CMakeLists.txt
Normal file
@ -0,0 +1,17 @@
|
||||
##============================================================================
|
||||
## 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.
|
||||
##============================================================================
|
||||
|
||||
set(headers
|
||||
aligned_union.h
|
||||
is_trivially_copyable.h
|
||||
void_t.h
|
||||
)
|
||||
|
||||
vtkm_declare_headers(${headers})
|
69
vtkmstd/aligned_union.h
Normal file
69
vtkmstd/aligned_union.h
Normal file
@ -0,0 +1,69 @@
|
||||
//============================================================================
|
||||
// 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_aligned_union_h
|
||||
#define vtk_m_std_aligned_union_h
|
||||
|
||||
#include <vtkm/internal/Configure.h>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#if defined(VTKM_USING_GLIBCXX_4)
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace vtkmstd
|
||||
{
|
||||
|
||||
template <std::size_t... Xs>
|
||||
struct max_size;
|
||||
template <std::size_t X>
|
||||
struct max_size<X>
|
||||
{
|
||||
static constexpr std::size_t value = X;
|
||||
};
|
||||
template <std::size_t X0, std::size_t... Xs>
|
||||
struct max_size<X0, Xs...>
|
||||
{
|
||||
static constexpr std::size_t other_value = max_size<Xs...>::value;
|
||||
static constexpr std::size_t value = (other_value > X0) ? other_value : X0;
|
||||
};
|
||||
|
||||
// This is to get around an apparent bug in GCC 4.8 where alianas(x) does not
|
||||
// seem to work when x is a constexpr. See
|
||||
// https://stackoverflow.com/questions/29879609/g-complains-constexpr-function-is-not-a-constant-expression
|
||||
template <std::size_t Alignment, std::size_t Size>
|
||||
struct aligned_data_block
|
||||
{
|
||||
alignas(Alignment) char _s[Size];
|
||||
};
|
||||
|
||||
template <std::size_t Len, class... Types>
|
||||
struct aligned_union
|
||||
{
|
||||
static constexpr std::size_t alignment_value = vtkmstd::max_size<alignof(Types)...>::value;
|
||||
|
||||
using type =
|
||||
vtkmstd::aligned_data_block<alignment_value, vtkmstd::max_size<Len, sizeof(Types)...>::value>;
|
||||
};
|
||||
|
||||
} // namespace vtkmstd
|
||||
|
||||
#else // NOT VTKM_USING_GLIBCXX_4
|
||||
|
||||
namespace vtkmstd
|
||||
{
|
||||
|
||||
using std::aligned_union;
|
||||
|
||||
} // namespace vtkmstd
|
||||
|
||||
#endif // NOT VTKM_USING_GLIBCXX_4
|
||||
|
||||
#endif //vtk_m_std_aligned_union_h
|
41
vtkmstd/is_trivially_copyable.h
Normal file
41
vtkmstd/is_trivially_copyable.h
Normal file
@ -0,0 +1,41 @@
|
||||
//============================================================================
|
||||
// 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_trivially_copyable_h
|
||||
#define vtk_m_std_is_trivially_copyable_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
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace vtkmstd
|
||||
|
||||
#else // NOT VTKM_USING_GLIBCXX_4
|
||||
namespace vtkmstd
|
||||
{
|
||||
|
||||
using std::is_trivially_copyable;
|
||||
|
||||
} // namespace vtkmstd
|
||||
#endif
|
||||
|
||||
#endif //vtk_m_std_is_trivially_copyable_h
|
40
vtkmstd/void_t.h
Normal file
40
vtkmstd/void_t.h
Normal file
@ -0,0 +1,40 @@
|
||||
//============================================================================
|
||||
// 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_void_t_h
|
||||
#define vtk_m_std_void_t_h
|
||||
|
||||
#include <vtkm/internal/Configure.h>
|
||||
|
||||
namespace vtkmstd
|
||||
{
|
||||
|
||||
/// Implementation of std::void_t (C++17):
|
||||
/// Allows for specialization of class templates based on members of template
|
||||
/// parameters.
|
||||
#if defined(VTKM_GCC) && (__GNUC__ < 5)
|
||||
// Due to a defect in the wording (CWG 1558) unused parameters in alias templates
|
||||
// were not guaranteed to ensure SFINAE, and therefore would consider everything
|
||||
// to match the 'true' side. For VTK-m the only known compiler that implemented
|
||||
// this defect is GCC < 5.
|
||||
template <class... T>
|
||||
struct void_pack
|
||||
{
|
||||
using type = void;
|
||||
};
|
||||
template <class... T>
|
||||
using void_t = typename void_pack<T...>::type;
|
||||
#else
|
||||
template <typename...>
|
||||
using void_t = void;
|
||||
#endif
|
||||
|
||||
} // end namespace vtkmstd
|
||||
|
||||
#endif //vtk_m_std_void_t_h
|
Loading…
Reference in New Issue
Block a user