]>
Commit | Line | Data |
---|---|---|
92f5a8d4 TL |
1 | /* |
2 | Copyright 2018 Glen Joseph Fernandes | |
3 | (glenjofe@gmail.com) | |
4 | ||
5 | Distributed under the Boost Software License, Version 1.0. | |
6 | (http://www.boost.org/LICENSE_1_0.txt) | |
7 | */ | |
8 | #ifndef BOOST_CORE_EMPTY_VALUE_HPP | |
9 | #define BOOST_CORE_EMPTY_VALUE_HPP | |
10 | ||
11 | #include <boost/config.hpp> | |
12 | #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) | |
13 | #include <utility> | |
14 | #endif | |
15 | ||
16 | #if defined(BOOST_GCC_VERSION) && (BOOST_GCC_VERSION >= 40700) | |
17 | #define BOOST_DETAIL_EMPTY_VALUE_BASE | |
18 | #elif defined(BOOST_INTEL) && defined(_MSC_VER) && (_MSC_VER >= 1800) | |
19 | #define BOOST_DETAIL_EMPTY_VALUE_BASE | |
20 | #elif defined(BOOST_MSVC) && (BOOST_MSVC >= 1800) | |
21 | #define BOOST_DETAIL_EMPTY_VALUE_BASE | |
22 | #elif defined(BOOST_CLANG) && !defined(__CUDACC__) | |
23 | #if __has_feature(is_empty) && __has_feature(is_final) | |
24 | #define BOOST_DETAIL_EMPTY_VALUE_BASE | |
25 | #endif | |
26 | #endif | |
27 | ||
28 | namespace boost { | |
29 | ||
30 | template<class T> | |
31 | struct use_empty_value_base { | |
32 | enum { | |
33 | #if defined(BOOST_DETAIL_EMPTY_VALUE_BASE) | |
34 | value = __is_empty(T) && !__is_final(T) | |
35 | #else | |
36 | value = false | |
37 | #endif | |
38 | }; | |
39 | }; | |
40 | ||
41 | struct empty_init_t { }; | |
42 | ||
43 | namespace empty_ { | |
44 | ||
45 | template<class T, unsigned N = 0, | |
46 | bool E = boost::use_empty_value_base<T>::value> | |
47 | class empty_value { | |
48 | public: | |
49 | typedef T type; | |
50 | ||
51 | #if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) | |
52 | empty_value() = default; | |
53 | #else | |
54 | empty_value() { } | |
55 | #endif | |
56 | ||
57 | empty_value(boost::empty_init_t) | |
58 | : value_() { } | |
59 | ||
60 | #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) | |
61 | #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) | |
20effc67 TL |
62 | template<class U, class... Args> |
63 | empty_value(boost::empty_init_t, U&& value, Args&&... args) | |
64 | : value_(std::forward<U>(value), std::forward<Args>(args)...) { } | |
92f5a8d4 TL |
65 | #else |
66 | template<class U> | |
67 | empty_value(boost::empty_init_t, U&& value) | |
68 | : value_(std::forward<U>(value)) { } | |
69 | #endif | |
70 | #else | |
71 | template<class U> | |
72 | empty_value(boost::empty_init_t, const U& value) | |
73 | : value_(value) { } | |
74 | ||
75 | template<class U> | |
76 | empty_value(boost::empty_init_t, U& value) | |
77 | : value_(value) { } | |
78 | #endif | |
79 | ||
80 | const T& get() const BOOST_NOEXCEPT { | |
81 | return value_; | |
82 | } | |
83 | ||
84 | T& get() BOOST_NOEXCEPT { | |
85 | return value_; | |
86 | } | |
87 | ||
88 | private: | |
89 | T value_; | |
90 | }; | |
91 | ||
92 | #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) | |
93 | template<class T, unsigned N> | |
94 | class empty_value<T, N, true> | |
95 | : T { | |
96 | public: | |
97 | typedef T type; | |
98 | ||
99 | #if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) | |
100 | empty_value() = default; | |
101 | #else | |
102 | empty_value() { } | |
103 | #endif | |
104 | ||
105 | empty_value(boost::empty_init_t) | |
106 | : T() { } | |
107 | ||
108 | #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) | |
109 | #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) | |
20effc67 TL |
110 | template<class U, class... Args> |
111 | empty_value(boost::empty_init_t, U&& value, Args&&... args) | |
112 | : T(std::forward<U>(value), std::forward<Args>(args)...) { } | |
92f5a8d4 TL |
113 | #else |
114 | template<class U> | |
115 | empty_value(boost::empty_init_t, U&& value) | |
116 | : T(std::forward<U>(value)) { } | |
117 | #endif | |
118 | #else | |
119 | template<class U> | |
120 | empty_value(boost::empty_init_t, const U& value) | |
121 | : T(value) { } | |
122 | ||
123 | template<class U> | |
124 | empty_value(boost::empty_init_t, U& value) | |
125 | : T(value) { } | |
126 | #endif | |
127 | ||
128 | const T& get() const BOOST_NOEXCEPT { | |
129 | return *this; | |
130 | } | |
131 | ||
132 | T& get() BOOST_NOEXCEPT { | |
133 | return *this; | |
134 | } | |
135 | }; | |
136 | #endif | |
137 | ||
138 | } /* empty_ */ | |
139 | ||
140 | using empty_::empty_value; | |
141 | ||
f67539c2 TL |
142 | BOOST_INLINE_CONSTEXPR empty_init_t empty_init = empty_init_t(); |
143 | ||
92f5a8d4 TL |
144 | } /* boost */ |
145 | ||
146 | #endif |