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 // [email protected] 11 12 #ifndef BOOST_OPTIONAL_DETAIL_EXPERIMENTAL_TRAITS_04NOV2017_HPP 13 #define BOOST_OPTIONAL_DETAIL_EXPERIMENTAL_TRAITS_04NOV2017_HPP 14 15 #include <boost/config.hpp> 16 #include <boost/detail/workaround.hpp> 17 #include <boost/predef.h> 18 #include <boost/type_traits.hpp> 19 20 // The condition to use POD implementation 21 22 #ifdef BOOST_OPTIONAL_CONFIG_NO_POD_SPEC 23 # define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES 24 #elif defined BOOST_OPTIONAL_CONFIG_NO_SPEC_FOR_TRIVIAL_TYPES 25 # define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES 26 #elif !defined BOOST_HAS_TRIVIAL_CONSTRUCTOR 27 # define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES 28 #elif !defined BOOST_HAS_TRIVIAL_MOVE_ASSIGN 29 # define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES 30 #elif !defined BOOST_HAS_TRIVIAL_MOVE_CONSTRUCTOR 31 # define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES 32 #elif !defined BOOST_HAS_TRIVIAL_COPY 33 # define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES 34 #elif !defined BOOST_HAS_TRIVIAL_ASSIGN 35 # define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES 36 #elif !defined BOOST_HAS_TRIVIAL_DESTRUCTOR 37 # define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES 38 #elif BOOST_WORKAROUND(BOOST_GCC, < 50000) 39 # define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES 40 #endif 41 42 // GCC 5 or higher, or clang with libc++ or clang with libstdc++ 5 or higher 43 #if __cplusplus >= 201103L 44 # if BOOST_WORKAROUND(BOOST_GCC, >= 50000) 45 # define BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS 46 # elif (defined BOOST_CLANG) 47 # if BOOST_LIB_STD_CXX > 0 48 # define BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS 49 # 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 50 # define BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS 51 # endif 52 # endif 53 #endif 54 55 56 #ifndef BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS 57 # define BOOST_OPTIONAL_DETAIL_HAS_TRIVIAL_CTOR(T) BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) 58 #else 59 # include <type_traits> 60 # define BOOST_OPTIONAL_DETAIL_HAS_TRIVIAL_CTOR(T) std::is_trivially_default_constructible<T>::value 61 #endif 62 63 64 namespace boost { namespace optional_detail { 65 66 #ifndef BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES 67 template <typename T> 68 struct is_type_trivially_copyable 69 : boost::conditional<(boost::has_trivial_copy_constructor<T>::value && 70 boost::has_trivial_move_constructor<T>::value && 71 boost::has_trivial_destructor<T>::value && 72 boost::has_trivial_move_assign<T>::value && 73 boost::has_trivial_assign<T>::value), 74 boost::true_type, boost::false_type>::type 75 {}; 76 #else 77 template <typename T> 78 struct is_type_trivially_copyable 79 : boost::conditional<(boost::is_scalar<T>::value && !boost::is_const<T>::value && !boost::is_volatile<T>::value), 80 boost::true_type, boost::false_type>::type 81 {}; 82 #endif 83 84 85 86 #ifndef BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES 87 template <typename T> 88 struct optional_uses_direct_storage_for_ 89 : boost::conditional< (is_type_trivially_copyable<T>::value && BOOST_OPTIONAL_DETAIL_HAS_TRIVIAL_CTOR(T)) || 90 (boost::is_scalar<T>::value && !boost::is_const<T>::value && !boost::is_volatile<T>::value) 91 , boost::true_type, boost::false_type>::type 92 {}; 93 #else 94 template <typename T> 95 struct optional_uses_direct_storage_for_ 96 : boost::conditional<(boost::is_scalar<T>::value && !boost::is_const<T>::value && !boost::is_volatile<T>::value) 97 , boost::true_type, boost::false_type>::type 98 {}; 99 #endif 100 101 102 }} // boost::optional_detail 103 104 #endif 105