From 584a8e07b29eb07d0df7558dc63530a2d0a6ccde Mon Sep 17 00:00:00 2001 From: Shreyans Doshi Date: Mon, 21 Aug 2017 03:29:23 +0530 Subject: [PATCH] [SetTheoretic] Add SetTheoretic concept It adds SetTheoretic concept for functions- union, intersection, difference, symmetric_difference. Closes https://github.com/boostorg/hana/issues/357 --- example/misc/infinite_set.cpp | 6 +++ include/boost/hana/concept.hpp | 1 + include/boost/hana/concept/set_theoretic.hpp | 37 +++++++++++++++++++ include/boost/hana/difference.hpp | 17 +++++++-- .../boost/hana/fwd/concept/set_theoretic.hpp | 37 +++++++++++++++++++ include/boost/hana/intersection.hpp | 17 +++++++-- include/boost/hana/map.hpp | 7 ++++ include/boost/hana/set.hpp | 6 +++ include/boost/hana/symmetric_difference.hpp | 17 +++++++-- include/boost/hana/union.hpp | 17 +++++++-- 10 files changed, 150 insertions(+), 12 deletions(-) create mode 100644 include/boost/hana/concept/set_theoretic.hpp create mode 100644 include/boost/hana/fwd/concept/set_theoretic.hpp diff --git a/example/misc/infinite_set.cpp b/example/misc/infinite_set.cpp index 6bccfd535c..dfd02e7f38 100644 --- a/example/misc/infinite_set.cpp +++ b/example/misc/infinite_set.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -48,6 +49,11 @@ constexpr auto doubleton(X x, Y y) { } namespace boost { namespace hana { + template <> + struct SetTheoretic { + static constexpr bool value = true; + }; + template <> struct union_impl { template diff --git a/include/boost/hana/concept.hpp b/include/boost/hana/concept.hpp index 6046b0a4ef..d26835a533 100644 --- a/include/boost/hana/concept.hpp +++ b/include/boost/hana/concept.hpp @@ -31,6 +31,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include +#include #include #endif // !BOOST_HANA_CONCEPT_HPP diff --git a/include/boost/hana/concept/set_theoretic.hpp b/include/boost/hana/concept/set_theoretic.hpp new file mode 100644 index 0000000000..859eec2bde --- /dev/null +++ b/include/boost/hana/concept/set_theoretic.hpp @@ -0,0 +1,37 @@ +/*! +@file +Defines `boost::hana::SetTheoretic`. + +@copyright Shreyans Doshi 2017 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + */ + +#ifndef BOOST_HANA_CONCEPT_SET_THEORETIC_HPP +#define BOOST_HANA_CONCEPT_SET_THEORETIC_HPP + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +BOOST_HANA_NAMESPACE_BEGIN + template + struct SetTheoretic + : hana::integral_constant::type>>::value && + !is_default::type>>::value && + !is_default::type>>::value && + !is_default::type>>::value + > + { }; +BOOST_HANA_NAMESPACE_END + +#endif // !BOOST_HANA_CONCEPT_SET_THEORETIC_HPP diff --git a/include/boost/hana/difference.hpp b/include/boost/hana/difference.hpp index d2e2897d6e..9d51c71e64 100644 --- a/include/boost/hana/difference.hpp +++ b/include/boost/hana/difference.hpp @@ -12,6 +12,7 @@ Distributed under the Boost Software License, Version 1.0. #include +#include #include #include #include @@ -21,11 +22,21 @@ BOOST_HANA_NAMESPACE_BEGIN //! @cond template constexpr auto difference_t::operator()(Xs&& xs, Ys&& ys) const { - using S = typename hana::tag_of::type; - using Difference = BOOST_HANA_DISPATCH_IF(difference_impl, - true + using TX = typename hana::tag_of::type; + using TY = typename hana::tag_of::type; + using Difference = BOOST_HANA_DISPATCH_IF(difference_impl, + hana::SetTheoretic::value && + std::is_same::value ); + #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS + static_assert(hana::SetTheoretic::value, + "hana::difference(xs, ys) requires 'xs' to be SetTheoretic"); + + static_assert(std::is_same::value, + "hana::difference(xs, ys) requires 'xs' and 'ys' to be SetTheoretic"); + #endif + return Difference::apply(static_cast(xs), static_cast(ys)); } //! @endcond diff --git a/include/boost/hana/fwd/concept/set_theoretic.hpp b/include/boost/hana/fwd/concept/set_theoretic.hpp new file mode 100644 index 0000000000..64e4474d9b --- /dev/null +++ b/include/boost/hana/fwd/concept/set_theoretic.hpp @@ -0,0 +1,37 @@ +/*! +@file +Forward declares `boost::hana::SetTheoretic`. + +@copyright Shreyans Doshi 2017 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + */ + +#ifndef BOOST_HANA_FWD_CONCEPT_SET_THEORETIC_HPP +#define BOOST_HANA_FWD_CONCEPT_SET_THEORETIC_HPP + +#include + + +BOOST_HANA_NAMESPACE_BEGIN + //! @ingroup group-concepts + //! @defgroup group-SetTheoretic SetTheoretic + //! The `SetTheoretic` concept represents data structures supporting + //! set-theoretic functions like union, instersection, difference, + //! and symmetric_difference. + //! + //! Minimal complete definition + //! --------------------------- + //! `union_`, `intersection`, `difference` and `symmetric_difference` + //! + //! Concrete models + //! --------------- + //! `hana::set`, `hana::map` + //! + //! + //! [1]: https://github.com/boostorg/hana/issues/357 + template + struct SetTheoretic; +BOOST_HANA_NAMESPACE_END + +#endif // !BOOST_HANA_FWD_CONCEPT_SET_THEORETIC_HPP diff --git a/include/boost/hana/intersection.hpp b/include/boost/hana/intersection.hpp index a9859d8f42..8f1cd920c6 100644 --- a/include/boost/hana/intersection.hpp +++ b/include/boost/hana/intersection.hpp @@ -12,6 +12,7 @@ Distributed under the Boost Software License, Version 1.0. #include +#include #include #include @@ -20,10 +21,20 @@ BOOST_HANA_NAMESPACE_BEGIN //! @cond template constexpr auto intersection_t::operator()(Xs&& xs, Ys&& ys) const { - using S = typename hana::tag_of::type; - using Intersection = BOOST_HANA_DISPATCH_IF(intersection_impl, - true + using TX = typename hana::tag_of::type; + using TY = typename hana::tag_of::type; + using Intersection = BOOST_HANA_DISPATCH_IF(intersection_impl, + hana::SetTheoretic::value && + std::is_same::value ); + + #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS + static_assert(hana::SetTheoretic::value, + "hana::intersection(xs, ys) requires 'xs' to be SetTheoretic"); + + static_assert(std::is_same::value, + "hana::intersection(xs, ys) requires 'xs' and 'ys' to be SetTheoretic"); + #endif return Intersection::apply(static_cast(xs), static_cast(ys)); } diff --git a/include/boost/hana/map.hpp b/include/boost/hana/map.hpp index 8da5012190..fbae8360a6 100644 --- a/include/boost/hana/map.hpp +++ b/include/boost/hana/map.hpp @@ -18,6 +18,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include +#include #include #include #include @@ -207,6 +208,12 @@ BOOST_HANA_NAMESPACE_BEGIN using type = detail::map_impl; }; } + + template <> + struct SetTheoretic { + static constexpr bool value = true; + }; + ////////////////////////////////////////////////////////////////////////// // make diff --git a/include/boost/hana/set.hpp b/include/boost/hana/set.hpp index 58979ed47f..0d1efcaca7 100644 --- a/include/boost/hana/set.hpp +++ b/include/boost/hana/set.hpp @@ -17,6 +17,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include +#include #include #include #include @@ -77,6 +78,11 @@ BOOST_HANA_NAMESPACE_BEGIN constexpr set(set&& other) = default; }; //! @endcond + + template <> + struct SetTheoretic { + static constexpr bool value = true; + }; ////////////////////////////////////////////////////////////////////////// // Operators diff --git a/include/boost/hana/symmetric_difference.hpp b/include/boost/hana/symmetric_difference.hpp index 1ca56d3019..7d15cc5e1e 100644 --- a/include/boost/hana/symmetric_difference.hpp +++ b/include/boost/hana/symmetric_difference.hpp @@ -12,6 +12,7 @@ Distributed under the Boost Software License, Version 1.0. #include +#include #include #include #include @@ -22,10 +23,20 @@ BOOST_HANA_NAMESPACE_BEGIN //! @cond template constexpr auto symmetric_difference_t::operator()(Xs&& xs, Ys&& ys) const { - using S = typename hana::tag_of::type; - using SymmetricDifference = BOOST_HANA_DISPATCH_IF(symmetric_difference_impl, - true + using TX = typename hana::tag_of::type; + using TY = typename hana::tag_of::type; + using SymmetricDifference = BOOST_HANA_DISPATCH_IF(symmetric_difference_impl, + hana::SetTheoretic::value && + std::is_same::value ); + + #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS + static_assert(hana::SetTheoretic::value, + "hana::symmetric_difference(xs, ys) requires 'xs' to be SetTheoretic"); + + static_assert(std::is_same::value, + "hana::symmetric_difference(xs, ys) requires 'xs' and 'ys' to be SetTheoretic"); + #endif return SymmetricDifference::apply(static_cast(xs), static_cast(ys)); } diff --git a/include/boost/hana/union.hpp b/include/boost/hana/union.hpp index d7bb4403bf..7eb1030d05 100644 --- a/include/boost/hana/union.hpp +++ b/include/boost/hana/union.hpp @@ -12,6 +12,7 @@ Distributed under the Boost Software License, Version 1.0. #include +#include #include #include @@ -20,11 +21,21 @@ BOOST_HANA_NAMESPACE_BEGIN //! @cond template constexpr auto union_t::operator()(Xs&& xs, Ys&& ys) const { - using S = typename hana::tag_of::type; - using Union = BOOST_HANA_DISPATCH_IF(union_impl, - true + using TX = typename hana::tag_of::type; + using TY = typename hana::tag_of::type; + using Union = BOOST_HANA_DISPATCH_IF(union_impl, + hana::SetTheoretic::value && + std::is_same::value ); + #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS + static_assert(hana::SetTheoretic::value, + "hana::union_(xs, ys) requires 'xs' to be SetTheoretic"); + + static_assert(std::is_same::value, + "hana::union_(xs, ys) requires 'xs' and 'ys' to be SetTheoretic"); + #endif + return Union::apply(static_cast(xs), static_cast(ys)); } //! @endcond