empty_value.hpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /*
  2. Copyright 2018 Glen Joseph Fernandes
  3. (glenjofe@gmail.com)
  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. namespace boost {
  25. template<class T>
  26. struct use_empty_value_base {
  27. enum {
  28. #if defined(BOOST_DETAIL_EMPTY_VALUE_BASE)
  29. value = __is_empty(T) && !__is_final(T)
  30. #else
  31. value = false
  32. #endif
  33. };
  34. };
  35. struct empty_init_t { };
  36. namespace empty_ {
  37. template<class T, unsigned N = 0,
  38. bool E = boost::use_empty_value_base<T>::value>
  39. class empty_value {
  40. public:
  41. typedef T type;
  42. #if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
  43. empty_value() = default;
  44. #else
  45. empty_value() { }
  46. #endif
  47. empty_value(boost::empty_init_t)
  48. : value_() { }
  49. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  50. #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  51. template<class... Args>
  52. explicit empty_value(boost::empty_init_t, Args&&... args)
  53. : value_(std::forward<Args>(args)...) { }
  54. #else
  55. template<class U>
  56. empty_value(boost::empty_init_t, U&& value)
  57. : value_(std::forward<U>(value)) { }
  58. #endif
  59. #else
  60. template<class U>
  61. empty_value(boost::empty_init_t, const U& value)
  62. : value_(value) { }
  63. template<class U>
  64. empty_value(boost::empty_init_t, U& value)
  65. : value_(value) { }
  66. #endif
  67. const T& get() const BOOST_NOEXCEPT {
  68. return value_;
  69. }
  70. T& get() BOOST_NOEXCEPT {
  71. return value_;
  72. }
  73. private:
  74. T value_;
  75. };
  76. #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
  77. template<class T, unsigned N>
  78. class empty_value<T, N, true>
  79. : T {
  80. public:
  81. typedef T type;
  82. #if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
  83. empty_value() = default;
  84. #else
  85. empty_value() { }
  86. #endif
  87. empty_value(boost::empty_init_t)
  88. : T() { }
  89. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  90. #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  91. template<class... Args>
  92. explicit empty_value(boost::empty_init_t, Args&&... args)
  93. : T(std::forward<Args>(args)...) { }
  94. #else
  95. template<class U>
  96. empty_value(boost::empty_init_t, U&& value)
  97. : T(std::forward<U>(value)) { }
  98. #endif
  99. #else
  100. template<class U>
  101. empty_value(boost::empty_init_t, const U& value)
  102. : T(value) { }
  103. template<class U>
  104. empty_value(boost::empty_init_t, U& value)
  105. : T(value) { }
  106. #endif
  107. const T& get() const BOOST_NOEXCEPT {
  108. return *this;
  109. }
  110. T& get() BOOST_NOEXCEPT {
  111. return *this;
  112. }
  113. };
  114. #endif
  115. } /* empty_ */
  116. using empty_::empty_value;
  117. } /* boost */
  118. #endif