empty_value.hpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. /////////////////////////////////////////////////////////////////////
  2. // Copyright 2018 Glen Joseph Fernandes.
  3. // Copyright 2021 Matt Borland. Distributed under the Boost
  4. // Software License, Version 1.0. (See accompanying file
  5. // LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
  6. #ifndef BOOST_MP_DETAIL_EMPTY_VALUE_HPP
  7. #define BOOST_MP_DETAIL_EMPTY_VALUE_HPP
  8. #include <utility>
  9. #include <boost/multiprecision/detail/standalone_config.hpp>
  10. #if defined(BOOST_GCC_VERSION) && (BOOST_GCC_VERSION >= 40700)
  11. #define BOOST_DETAIL_EMPTY_VALUE_BASE
  12. #elif defined(BOOST_INTEL) && defined(_MSC_VER) && (_MSC_VER >= 1800)
  13. #define BOOST_DETAIL_EMPTY_VALUE_BASE
  14. #elif defined(BOOST_MSVC) && (BOOST_MSVC >= 1800)
  15. #define BOOST_DETAIL_EMPTY_VALUE_BASE
  16. #elif defined(BOOST_CLANG) && !defined(__CUDACC__)
  17. #if __has_feature(is_empty) && __has_feature(is_final)
  18. #define BOOST_DETAIL_EMPTY_VALUE_BASE
  19. #endif
  20. #endif
  21. namespace boost { namespace multiprecision { namespace detail {
  22. template <typename T>
  23. struct use_empty_value_base
  24. {
  25. #if defined(BOOST_DETAIL_EMPTY_VALUE_BASE)
  26. static constexpr bool value = __is_empty(T) && !__is_final(T);
  27. #else
  28. static constexpr bool value = false;
  29. #endif
  30. };
  31. struct empty_init_t {};
  32. namespace empty_impl {
  33. template <typename T, unsigned N = 0,
  34. bool E = boost::multiprecision::detail::use_empty_value_base<T>::value>
  35. class empty_value
  36. {
  37. private:
  38. T value_;
  39. public:
  40. using type = T;
  41. empty_value() = default;
  42. explicit empty_value(boost::multiprecision::detail::empty_init_t) : value_ {} {}
  43. template <typename U, typename... Args>
  44. empty_value(boost::multiprecision::detail::empty_init_t, U&& value, Args&&... args) :
  45. value_ {std::forward<U>(value), std::forward<Args>(args)...} {}
  46. const T& get() const noexcept { return value_; }
  47. T& get() noexcept { return value_; }
  48. };
  49. template <typename T, unsigned N>
  50. class empty_value<T, N, true> : T
  51. {
  52. public:
  53. using type = T;
  54. empty_value() = default;
  55. explicit empty_value(boost::multiprecision::detail::empty_init_t) : T{} {}
  56. template <typename U, typename... Args>
  57. empty_value(boost::multiprecision::detail::empty_init_t, U&& value, Args&&... args) :
  58. T{std::forward<U>(value), std::forward<Args>(args)...} {}
  59. const T& get() const noexcept { return *this; }
  60. T& get() noexcept { return *this; }
  61. };
  62. } // Namespace empty impl
  63. using empty_impl::empty_value;
  64. BOOST_INLINE_CONSTEXPR empty_init_t empty_init = empty_init_t();
  65. }}} // Namespaces
  66. #endif // BOOST_MP_DETAIL_EMPTY_VALUE_HPP