empty_value.hpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  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. #endif
  64. const T& get() const BOOST_NOEXCEPT {
  65. return value_;
  66. }
  67. T& get() BOOST_NOEXCEPT {
  68. return value_;
  69. }
  70. private:
  71. T value_;
  72. };
  73. #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
  74. template<class T, unsigned N>
  75. class empty_value<T, N, true>
  76. : T {
  77. public:
  78. typedef T type;
  79. #if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
  80. empty_value() = default;
  81. #else
  82. empty_value() { }
  83. #endif
  84. empty_value(boost::empty_init_t)
  85. : T() { }
  86. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  87. #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  88. template<class... Args>
  89. explicit empty_value(boost::empty_init_t, Args&&... args)
  90. : T(std::forward<Args>(args)...) { }
  91. #else
  92. template<class U>
  93. empty_value(boost::empty_init_t, U&& value)
  94. : T(std::forward<U>(value)) { }
  95. #endif
  96. #else
  97. template<class U>
  98. empty_value(boost::empty_init_t, const U& value)
  99. : T(value) { }
  100. #endif
  101. const T& get() const BOOST_NOEXCEPT {
  102. return *this;
  103. }
  104. T& get() BOOST_NOEXCEPT {
  105. return *this;
  106. }
  107. };
  108. #endif
  109. } /* empty_ */
  110. using empty_::empty_value;
  111. } /* boost */
  112. #endif