Brian Silverman | af2eaa8 | 2018-08-04 17:28:31 -0700 | [diff] [blame^] | 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 | |
| 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 |