is_subset.hpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /*!
  2. @file
  3. Defines `boost::hana::is_subset`.
  4. Copyright Louis Dionne 2013-2022
  5. Distributed under the Boost Software License, Version 1.0.
  6. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
  7. */
  8. #ifndef BOOST_HANA_IS_SUBSET_HPP
  9. #define BOOST_HANA_IS_SUBSET_HPP
  10. #include <boost/hana/fwd/is_subset.hpp>
  11. #include <boost/hana/all_of.hpp>
  12. #include <boost/hana/concept/searchable.hpp>
  13. #include <boost/hana/config.hpp>
  14. #include <boost/hana/contains.hpp>
  15. #include <boost/hana/core/common.hpp>
  16. #include <boost/hana/core/to.hpp>
  17. #include <boost/hana/core/dispatch.hpp>
  18. #include <boost/hana/detail/has_common_embedding.hpp>
  19. #include <boost/hana/functional/partial.hpp>
  20. namespace boost { namespace hana {
  21. //! @cond
  22. template <typename Xs, typename Ys>
  23. constexpr auto is_subset_t::operator()(Xs&& xs, Ys&& ys) const {
  24. using S1 = typename hana::tag_of<Xs>::type;
  25. using S2 = typename hana::tag_of<Ys>::type;
  26. using IsSubset = BOOST_HANA_DISPATCH_IF(
  27. decltype(is_subset_impl<S1, S2>{}),
  28. hana::Searchable<S1>::value &&
  29. hana::Searchable<S2>::value &&
  30. !is_default<is_subset_impl<S1, S2>>::value
  31. );
  32. #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
  33. static_assert(hana::Searchable<S1>::value,
  34. "hana::is_subset(xs, ys) requires 'xs' to be Searchable");
  35. static_assert(hana::Searchable<S2>::value,
  36. "hana::is_subset(xs, ys) requires 'ys' to be Searchable");
  37. static_assert(!is_default<is_subset_impl<S1, S2>>::value,
  38. "hana::is_subset(xs, ys) requires 'xs' and 'ys' to be embeddable "
  39. "in a common Searchable");
  40. #endif
  41. return IsSubset::apply(static_cast<Xs&&>(xs), static_cast<Ys&&>(ys));
  42. }
  43. //! @endcond
  44. template <typename S1, typename S2, bool condition>
  45. struct is_subset_impl<S1, S2, when<condition>> : default_ {
  46. template <typename ...Args>
  47. static constexpr auto apply(Args&& ...) = delete;
  48. };
  49. template <typename S, bool condition>
  50. struct is_subset_impl<S, S, when<condition>> {
  51. template <typename Xs, typename Ys>
  52. static constexpr decltype(auto) apply(Xs&& xs, Ys&& ys) {
  53. return hana::all_of(static_cast<Xs&&>(xs),
  54. hana::partial(hana::contains, static_cast<Ys&&>(ys)));
  55. }
  56. };
  57. // Cross-type overload
  58. template <typename S1, typename S2>
  59. struct is_subset_impl<S1, S2, when<
  60. detail::has_nontrivial_common_embedding<Searchable, S1, S2>::value
  61. >> {
  62. using C = typename common<S1, S2>::type;
  63. template <typename Xs, typename Ys>
  64. static constexpr decltype(auto) apply(Xs&& xs, Ys&& ys) {
  65. return hana::is_subset(hana::to<C>(static_cast<Xs&&>(xs)),
  66. hana::to<C>(static_cast<Ys&&>(ys)));
  67. }
  68. };
  69. }} // end namespace boost::hana
  70. #endif // !BOOST_HANA_IS_SUBSET_HPP