diff --git a/example/misc/infinite_set.cpp b/example/misc/infinite_set.cpp index 6bccfd535c..925a0bc822 100644 --- a/example/misc/infinite_set.cpp +++ b/example/misc/infinite_set.cpp @@ -8,9 +8,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -48,6 +51,9 @@ constexpr auto doubleton(X x, Y y) { } namespace boost { namespace hana { + ////////////////////////////////////////////////////////////////////////// + // SetTheoretic + ////////////////////////////////////////////////////////////////////////// template <> struct union_impl { template @@ -56,6 +62,22 @@ namespace boost { namespace hana { } }; + template <> + struct difference_impl { + template + static constexpr auto apply(Xs xs, Ys ys) { + return difference_impl(xs, ys); + } + }; + + template <> + struct intersection_impl { + template + static constexpr auto apply(Xs xs, Ys ys) { + return intersection_impl(xs, ys); + } + }; + ////////////////////////////////////////////////////////////////////////// // Comparable ////////////////////////////////////////////////////////////////////////// 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..8c2dc9820e --- /dev/null +++ b/include/boost/hana/concept/set_theoretic.hpp @@ -0,0 +1,36 @@ +/*! +@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 + > + { }; +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..4f63b8a39f 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 of the same type"); + #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..e239a65543 --- /dev/null +++ b/include/boost/hana/fwd/concept/set_theoretic.hpp @@ -0,0 +1,35 @@ +/*! +@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 + //! algebra of sets. + //! + //! Minimal complete definition + //! --------------------------- + //! `union_`, `intersection`, `difference` and `symmetric_difference` + //! + //! Concrete models + //! --------------- + //! `hana::set`, `hana::map` + //! + //! + 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..1b6ecc8878 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,11 +21,21 @@ 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 of the same type"); + #endif + return Intersection::apply(static_cast(xs), static_cast(ys)); } //! @endcond diff --git a/include/boost/hana/union.hpp b/include/boost/hana/union.hpp index d7bb4403bf..da672a53e0 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 of the same type"); + #endif + return Union::apply(static_cast(xs), static_cast(ys)); } //! @endcond