experimental_traits.hpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // Copyright (C) 2017 Andrzej Krzemienski.
  2. //
  3. // Use, modification, and distribution is subject to the Boost Software
  4. // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // See http://www.boost.org/libs/optional for documentation.
  8. //
  9. // You are welcome to contact the author at:
  10. // akrzemi1@gmail.com
  11. #ifndef BOOST_OPTIONAL_DETAIL_EXPERIMENTAL_TRAITS_04NOV2017_HPP
  12. #define BOOST_OPTIONAL_DETAIL_EXPERIMENTAL_TRAITS_04NOV2017_HPP
  13. #include <boost/config.hpp>
  14. #include <boost/detail/workaround.hpp>
  15. #include <boost/predef.h>
  16. #include <boost/type_traits.hpp>
  17. // The condition to use POD implementation
  18. #ifdef BOOST_OPTIONAL_CONFIG_NO_POD_SPEC
  19. # define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
  20. #elif defined BOOST_OPTIONAL_CONFIG_NO_SPEC_FOR_TRIVIAL_TYPES
  21. # define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
  22. #elif !defined BOOST_HAS_TRIVIAL_CONSTRUCTOR
  23. # define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
  24. #elif !defined BOOST_HAS_TRIVIAL_MOVE_ASSIGN
  25. # define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
  26. #elif !defined BOOST_HAS_TRIVIAL_MOVE_CONSTRUCTOR
  27. # define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
  28. #elif !defined BOOST_HAS_TRIVIAL_COPY
  29. # define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
  30. #elif !defined BOOST_HAS_TRIVIAL_ASSIGN
  31. # define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
  32. #elif !defined BOOST_HAS_TRIVIAL_DESTRUCTOR
  33. # define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
  34. #elif BOOST_WORKAROUND(BOOST_GCC, < 50000)
  35. # define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
  36. #endif
  37. // GCC 5 or higher, or clang with libc++ or clang with libstdc++ 5 or higher
  38. #if __cplusplus >= 201103L
  39. # if BOOST_WORKAROUND(BOOST_GCC, >= 50000)
  40. # define BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS
  41. # elif (defined BOOST_CLANG)
  42. # if BOOST_LIB_STD_CXX > 0
  43. # define BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS
  44. # elif BOOST_LIB_STD_GNU >= 441200023 && BOOST_LIB_STD_GNU != 450600023 && BOOST_LIB_STD_GNU != 450600026 && BOOST_LIB_STD_GNU != 460800003 && BOOST_LIB_STD_GNU != 450400026 && BOOST_LIB_STD_GNU != 460700026
  45. # define BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS
  46. # endif
  47. # endif
  48. #endif
  49. #ifndef BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS
  50. # define BOOST_OPTIONAL_DETAIL_HAS_TRIVIAL_CTOR(T) BOOST_HAS_TRIVIAL_CONSTRUCTOR(T)
  51. #else
  52. # include <type_traits>
  53. # define BOOST_OPTIONAL_DETAIL_HAS_TRIVIAL_CTOR(T) std::is_trivially_default_constructible<T>::value
  54. #endif
  55. namespace boost { namespace optional_detail {
  56. #ifndef BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
  57. template <typename T>
  58. struct is_type_trivially_copyable
  59. : boost::conditional<(boost::has_trivial_copy_constructor<T>::value &&
  60. boost::has_trivial_move_constructor<T>::value &&
  61. boost::has_trivial_destructor<T>::value &&
  62. boost::has_trivial_move_assign<T>::value &&
  63. boost::has_trivial_assign<T>::value),
  64. boost::true_type, boost::false_type>::type
  65. {};
  66. #else
  67. template <typename T>
  68. struct is_type_trivially_copyable
  69. : boost::conditional<(boost::is_scalar<T>::value && !boost::is_const<T>::value && !boost::is_volatile<T>::value),
  70. boost::true_type, boost::false_type>::type
  71. {};
  72. #endif
  73. #ifndef BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
  74. template <typename T>
  75. struct optional_uses_direct_storage_for_
  76. : boost::conditional< (is_type_trivially_copyable<T>::value && BOOST_OPTIONAL_DETAIL_HAS_TRIVIAL_CTOR(T)) ||
  77. (boost::is_scalar<T>::value && !boost::is_const<T>::value && !boost::is_volatile<T>::value)
  78. , boost::true_type, boost::false_type>::type
  79. {};
  80. #else
  81. template <typename T>
  82. struct optional_uses_direct_storage_for_
  83. : boost::conditional<(boost::is_scalar<T>::value && !boost::is_const<T>::value && !boost::is_volatile<T>::value)
  84. , boost::true_type, boost::false_type>::type
  85. {};
  86. #endif
  87. }} // boost::optional_detail
  88. #endif