empty_value.hpp 3.6 KB

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