traits.hpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. // Copyright (c) 2022 Denis Mikhailov
  2. //
  3. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef BOOST_PFR_TRAITS_HPP
  6. #define BOOST_PFR_TRAITS_HPP
  7. #pragma once
  8. #include <boost/pfr/detail/config.hpp>
  9. #if !defined(BOOST_USE_MODULES) || defined(BOOST_PFR_INTERFACE_UNIT)
  10. #include <boost/pfr/detail/possible_reflectable.hpp>
  11. #if !defined(BOOST_PFR_INTERFACE_UNIT)
  12. #include <type_traits>
  13. #endif
  14. /// \file boost/pfr/traits.hpp
  15. /// Contains traits \forcedlink{is_reflectable} and \forcedlink{is_implicitly_reflectable} for detecting an ability to reflect type.
  16. ///
  17. /// \b Synopsis:
  18. namespace boost { namespace pfr {
  19. BOOST_PFR_BEGIN_MODULE_EXPORT
  20. /// Has a static const member variable `value` when it is known that type T can or can't be reflected using Boost.PFR; otherwise, there is no member variable.
  21. /// Every user may (and in some difficult cases - should) specialize is_reflectable on his own.
  22. ///
  23. /// \b Example:
  24. /// \code
  25. /// namespace boost { namespace pfr {
  26. /// template<class All> struct is_reflectable<A, All> : std::false_type {}; // 'A' won't be interpreted as reflectable everywhere
  27. /// template<> struct is_reflectable<B, boost_fusion_tag> : std::false_type {}; // 'B' won't be interpreted as reflectable in only Boost Fusion
  28. /// }}
  29. /// \endcode
  30. /// \note is_reflectable affects is_implicitly_reflectable, the decision made by is_reflectable is used by is_implicitly_reflectable.
  31. template<class T, class WhatFor>
  32. struct is_reflectable { /* does not have 'value' because value is unknown */ };
  33. // these specs can't be inherited from 'std::integral_constant< bool, boost::pfr::is_reflectable<T, WhatFor>::value >',
  34. // because it will break the sfinae-friendliness
  35. template<class T, class WhatFor>
  36. struct is_reflectable<const T, WhatFor> : boost::pfr::is_reflectable<T, WhatFor> {};
  37. template<class T, class WhatFor>
  38. struct is_reflectable<volatile T, WhatFor> : boost::pfr::is_reflectable<T, WhatFor> {};
  39. template<class T, class WhatFor>
  40. struct is_reflectable<const volatile T, WhatFor> : boost::pfr::is_reflectable<T, WhatFor> {};
  41. /// Checks the input type for the potential to be reflected.
  42. /// Specialize is_reflectable if you disagree with is_implicitly_reflectable's default decision.
  43. template<class T, class WhatFor>
  44. using is_implicitly_reflectable = std::integral_constant< bool, boost::pfr::detail::possible_reflectable<T, WhatFor>(1L) >;
  45. /// Checks the input type for the potential to be reflected.
  46. /// Specialize is_reflectable if you disagree with is_implicitly_reflectable_v's default decision.
  47. template<class T, class WhatFor>
  48. constexpr bool is_implicitly_reflectable_v = is_implicitly_reflectable<T, WhatFor>::value;
  49. BOOST_PFR_END_MODULE_EXPORT
  50. }} // namespace boost::pfr
  51. #endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_PFR_INTERFACE_UNIT)
  52. #endif // BOOST_PFR_TRAITS_HPP