blob: b51f5f104491bded5a35414b2a5d840181b83f82 [file] [log] [blame]
Brian Silvermanaf2eaa82018-08-04 17:28:31 -07001// 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
64namespace boost { namespace optional_detail {
65
66#ifndef BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
67template <typename T>
68struct 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
77template <typename T>
78struct 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
87template <typename T>
88struct 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
94template <typename T>
95struct 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