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 empty_value()54 empty_value() { } 55 #endif 56 empty_value(boost::empty_init_t)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) 62 template<class U, class... Args> empty_value(boost::empty_init_t,U && value,Args &&...args)63 empty_value(boost::empty_init_t, U&& value, Args&&... args) 64 : value_(std::forward<U>(value), std::forward<Args>(args)...) { } 65 #else 66 template<class U> empty_value(boost::empty_init_t,U && value)67 empty_value(boost::empty_init_t, U&& value) 68 : value_(std::forward<U>(value)) { } 69 #endif 70 #else 71 template<class U> empty_value(boost::empty_init_t,const U & value)72 empty_value(boost::empty_init_t, const U& value) 73 : value_(value) { } 74 75 template<class U> empty_value(boost::empty_init_t,U & value)76 empty_value(boost::empty_init_t, U& value) 77 : value_(value) { } 78 #endif 79 get() const80 const T& get() const BOOST_NOEXCEPT { 81 return value_; 82 } 83 get()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 empty_value()102 empty_value() { } 103 #endif 104 empty_value(boost::empty_init_t)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) 110 template<class U, class... Args> empty_value(boost::empty_init_t,U && value,Args &&...args)111 empty_value(boost::empty_init_t, U&& value, Args&&... args) 112 : T(std::forward<U>(value), std::forward<Args>(args)...) { } 113 #else 114 template<class U> empty_value(boost::empty_init_t,U && value)115 empty_value(boost::empty_init_t, U&& value) 116 : T(std::forward<U>(value)) { } 117 #endif 118 #else 119 template<class U> empty_value(boost::empty_init_t,const U & value)120 empty_value(boost::empty_init_t, const U& value) 121 : T(value) { } 122 123 template<class U> empty_value(boost::empty_init_t,U & value)124 empty_value(boost::empty_init_t, U& value) 125 : T(value) { } 126 #endif 127 get() const128 const T& get() const BOOST_NOEXCEPT { 129 return *this; 130 } 131 get()132 T& get() BOOST_NOEXCEPT { 133 return *this; 134 } 135 }; 136 #endif 137 138 } /* empty_ */ 139 140 using empty_::empty_value; 141 142 BOOST_INLINE_CONSTEXPR empty_init_t empty_init = empty_init_t(); 143 144 } /* boost */ 145 146 #endif 147