summaryrefslogtreecommitdiff
path: root/boost/hana
diff options
context:
space:
mode:
Diffstat (limited to 'boost/hana')
-rw-r--r--boost/hana/empty.hpp16
-rw-r--r--boost/hana/experimental/printable.hpp2
-rw-r--r--boost/hana/ext/boost/mpl/vector.hpp18
-rw-r--r--boost/hana/fwd/basic_tuple.hpp5
-rw-r--r--boost/hana/fwd/empty.hpp4
-rw-r--r--boost/hana/fwd/lift.hpp5
-rw-r--r--boost/hana/fwd/map.hpp8
-rw-r--r--boost/hana/fwd/monadic_fold_left.hpp8
-rw-r--r--boost/hana/fwd/monadic_fold_right.hpp8
-rw-r--r--boost/hana/fwd/one.hpp4
-rw-r--r--boost/hana/fwd/optional.hpp5
-rw-r--r--boost/hana/fwd/pair.hpp5
-rw-r--r--boost/hana/fwd/product.hpp5
-rw-r--r--boost/hana/fwd/range.hpp3
-rw-r--r--boost/hana/fwd/replicate.hpp5
-rw-r--r--boost/hana/fwd/set.hpp3
-rw-r--r--boost/hana/fwd/string.hpp6
-rw-r--r--boost/hana/fwd/sum.hpp5
-rw-r--r--boost/hana/fwd/tap.hpp5
-rw-r--r--boost/hana/fwd/tuple.hpp5
-rw-r--r--boost/hana/fwd/type.hpp21
-rw-r--r--boost/hana/fwd/zero.hpp4
-rw-r--r--boost/hana/lift.hpp18
-rw-r--r--boost/hana/map.hpp2
-rw-r--r--boost/hana/monadic_fold_left.hpp64
-rw-r--r--boost/hana/monadic_fold_right.hpp64
-rw-r--r--boost/hana/one.hpp16
-rw-r--r--boost/hana/product.hpp30
-rw-r--r--boost/hana/replicate.hpp30
-rw-r--r--boost/hana/set.hpp2
-rw-r--r--boost/hana/sum.hpp30
-rw-r--r--boost/hana/tap.hpp18
-rw-r--r--boost/hana/tuple.hpp4
-rw-r--r--boost/hana/type.hpp47
-rw-r--r--boost/hana/version.hpp2
-rw-r--r--boost/hana/zero.hpp16
36 files changed, 308 insertions, 185 deletions
diff --git a/boost/hana/empty.hpp b/boost/hana/empty.hpp
index 8cb97a3ebc..86b81f408c 100644
--- a/boost/hana/empty.hpp
+++ b/boost/hana/empty.hpp
@@ -20,21 +20,21 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN
+ //! @cond
template <typename M>
- struct empty_t {
+ constexpr auto empty_t<M>::operator()() const {
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::MonadPlus<M>::value,
"hana::empty<M>() requires 'M' to be a MonadPlus");
#endif
- constexpr auto operator()() const {
- using Empty = BOOST_HANA_DISPATCH_IF(empty_impl<M>,
- hana::MonadPlus<M>::value
- );
+ using Empty = BOOST_HANA_DISPATCH_IF(empty_impl<M>,
+ hana::MonadPlus<M>::value
+ );
- return Empty::apply();
- }
- };
+ return Empty::apply();
+ }
+ //! @endcond
template <typename M, bool condition>
struct empty_impl<M, when<condition>> : default_ {
diff --git a/boost/hana/experimental/printable.hpp b/boost/hana/experimental/printable.hpp
index e24a3426ea..f41d3fd906 100644
--- a/boost/hana/experimental/printable.hpp
+++ b/boost/hana/experimental/printable.hpp
@@ -99,7 +99,7 @@ BOOST_HANA_NAMESPACE_BEGIN namespace experimental {
namespace print_detail {
std::string strip_type_junk(std::string const& str) {
- return std::regex_replace(str, std::regex("^([a-z_]+::)*([a-z_]*)_t<"), "$2<");
+ return std::regex_replace(str, std::regex("(?:struct )?([a-z_]+::)*([a-z_]*)_t<((?:struct )?[a-z:<>_]*)>"), "$2<$3>");
}
}
diff --git a/boost/hana/ext/boost/mpl/vector.hpp b/boost/hana/ext/boost/mpl/vector.hpp
index 29e9972b5d..706c2dd06d 100644
--- a/boost/hana/ext/boost/mpl/vector.hpp
+++ b/boost/hana/ext/boost/mpl/vector.hpp
@@ -99,9 +99,25 @@ BOOST_HANA_NAMESPACE_BEGIN
using vector_tag = ::boost::mpl::sequence_tag< ::boost::mpl::vector<>>::type;
}}}
+ namespace mpl_detail {
+ // When `BOOST_MPL_CFG_TYPEOF_BASED_SEQUENCES` is not defined (e.g. on
+ // MSVC), different MPL sequences (like vector0 and vector1) have different
+ // tags, so we need to take that into account when we compare them.
+#ifndef BOOST_MPL_CFG_TYPEOF_BASED_SEQUENCES
+ template <typename T1, typename T2>
+ struct is_same_mpl_vector_tag : std::false_type { };
+
+ template <template <long> class Tag, long x, long y>
+ struct is_same_mpl_vector_tag<Tag<x>, Tag<y>> : std::true_type { };
+#else
+ template <typename T1, typename T2>
+ struct is_same_mpl_vector_tag : std::is_same<T1, T2> { };
+#endif
+ }
+
template <typename T>
struct tag_of<T, when<
- std::is_same<
+ mpl_detail::is_same_mpl_vector_tag<
typename ::boost::mpl::sequence_tag<T>::type,
::boost::mpl::sequence_tag< ::boost::mpl::vector<>>::type
>::value
diff --git a/boost/hana/fwd/basic_tuple.hpp b/boost/hana/fwd/basic_tuple.hpp
index 8444f0f50e..69d4073f03 100644
--- a/boost/hana/fwd/basic_tuple.hpp
+++ b/boost/hana/fwd/basic_tuple.hpp
@@ -22,6 +22,11 @@ BOOST_HANA_NAMESPACE_BEGIN
//! `std::tuple`, `basic_tuple` provides the strict minimum required to
//! implement a closure with maximum compile-time efficiency.
//!
+ //! @note
+ //! When you use a container, remember not to make assumptions about its
+ //! representation, unless the documentation gives you those guarantees.
+ //! More details [in the tutorial](@ref tutorial-containers-types).
+ //!
//!
//! Modeled concepts
//! ----------------
diff --git a/boost/hana/fwd/empty.hpp b/boost/hana/fwd/empty.hpp
index ed3cc38cc7..719f58055f 100644
--- a/boost/hana/fwd/empty.hpp
+++ b/boost/hana/fwd/empty.hpp
@@ -41,7 +41,9 @@ BOOST_HANA_NAMESPACE_BEGIN
struct empty_impl : empty_impl<M, when<true>> { };
template <typename M>
- struct empty_t;
+ struct empty_t {
+ constexpr auto operator()() const;
+ };
template <typename M>
constexpr empty_t<M> empty{};
diff --git a/boost/hana/fwd/lift.hpp b/boost/hana/fwd/lift.hpp
index 9491dab8a4..2d4ac6cc13 100644
--- a/boost/hana/fwd/lift.hpp
+++ b/boost/hana/fwd/lift.hpp
@@ -49,7 +49,10 @@ BOOST_HANA_NAMESPACE_BEGIN
struct lift_impl : lift_impl<A, when<true>> { };
template <typename A>
- struct lift_t;
+ struct lift_t {
+ template <typename X>
+ constexpr auto operator()(X&& x) const;
+ };
template <typename A>
constexpr lift_t<A> lift{};
diff --git a/boost/hana/fwd/map.hpp b/boost/hana/fwd/map.hpp
index c00f57195f..782b0f1e97 100644
--- a/boost/hana/fwd/map.hpp
+++ b/boost/hana/fwd/map.hpp
@@ -36,21 +36,23 @@ BOOST_HANA_NAMESPACE_BEGIN
//! keys must be `Hashable`, and any two keys with equal hashes must be
//! `Comparable` with each other at compile-time.
//!
- //! Note that the actual representation of a `hana::map` is an implementation
+ //! @note
+ //! The actual representation of a `hana::map` is an implementation
//! detail. As such, one should not assume anything more than what is
//! explicitly documented as being part of the interface of a map,
//! such as:
//! - the presence of additional constructors
//! - the presence of additional assignment operators
//! - the fact that `hana::map<Pairs...>` is, or is not, a dependent type
- //!
+ //! .
//! In particular, the last point is very important; `hana::map<Pairs...>`
//! is basically equivalent to
//! @code
//! decltype(hana::make_pair(std::declval<Pairs>()...))
//! @endcode
//! which is not something that can be pattern-matched on during template
- //! argument deduction, for example.
+ //! argument deduction, for example. More details [in the tutorial]
+ //! (@ref tutorial-containers-types).
//!
//!
//! Modeled concepts
diff --git a/boost/hana/fwd/monadic_fold_left.hpp b/boost/hana/fwd/monadic_fold_left.hpp
index c037989dea..aa66097b3e 100644
--- a/boost/hana/fwd/monadic_fold_left.hpp
+++ b/boost/hana/fwd/monadic_fold_left.hpp
@@ -94,7 +94,13 @@ BOOST_HANA_NAMESPACE_BEGIN
struct monadic_fold_left_impl : monadic_fold_left_impl<T, when<true>> { };
template <typename M>
- struct monadic_fold_left_t;
+ struct monadic_fold_left_t {
+ template <typename Xs, typename State, typename F>
+ constexpr decltype(auto) operator()(Xs&& xs, State&& state, F&& f) const;
+
+ template <typename Xs, typename F>
+ constexpr decltype(auto) operator()(Xs&& xs, F&& f) const;
+ };
template <typename M>
constexpr monadic_fold_left_t<M> monadic_fold_left{};
diff --git a/boost/hana/fwd/monadic_fold_right.hpp b/boost/hana/fwd/monadic_fold_right.hpp
index 2028e15369..fff6fc0c1f 100644
--- a/boost/hana/fwd/monadic_fold_right.hpp
+++ b/boost/hana/fwd/monadic_fold_right.hpp
@@ -96,7 +96,13 @@ BOOST_HANA_NAMESPACE_BEGIN
struct monadic_fold_right_impl : monadic_fold_right_impl<T, when<true>> { };
template <typename M>
- struct monadic_fold_right_t;
+ struct monadic_fold_right_t {
+ template <typename Xs, typename State, typename F>
+ constexpr decltype(auto) operator()(Xs&& xs, State&& state, F&& f) const;
+
+ template <typename Xs, typename F>
+ constexpr decltype(auto) operator()(Xs&& xs, F&& f) const;
+ };
template <typename M>
constexpr monadic_fold_right_t<M> monadic_fold_right{};
diff --git a/boost/hana/fwd/one.hpp b/boost/hana/fwd/one.hpp
index d2c67b7228..27d4f37bd6 100644
--- a/boost/hana/fwd/one.hpp
+++ b/boost/hana/fwd/one.hpp
@@ -35,7 +35,9 @@ BOOST_HANA_NAMESPACE_BEGIN
struct one_impl : one_impl<R, when<true>> { };
template <typename R>
- struct one_t;
+ struct one_t {
+ constexpr decltype(auto) operator()() const;
+ };
template <typename R>
constexpr one_t<R> one{};
diff --git a/boost/hana/fwd/optional.hpp b/boost/hana/fwd/optional.hpp
index 28bb68e8af..8a348a8b12 100644
--- a/boost/hana/fwd/optional.hpp
+++ b/boost/hana/fwd/optional.hpp
@@ -38,6 +38,11 @@ BOOST_HANA_NAMESPACE_BEGIN
//! by the compiler. This makes `hana::optional` well suited for static
//! metaprogramming tasks, but very poor for anything dynamic.
//!
+ //! @note
+ //! When you use a container, remember not to make assumptions about its
+ //! representation, unless the documentation gives you those guarantees.
+ //! More details [in the tutorial](@ref tutorial-containers-types).
+ //!
//!
//! Interoperation with `type`s
//! ---------------------------
diff --git a/boost/hana/fwd/pair.hpp b/boost/hana/fwd/pair.hpp
index 897e87ad12..1ce0e22772 100644
--- a/boost/hana/fwd/pair.hpp
+++ b/boost/hana/fwd/pair.hpp
@@ -24,6 +24,11 @@ BOOST_HANA_NAMESPACE_BEGIN
//! Instead, one must use the `hana::first` and `hana::second` free
//! functions to access the elements of a pair.
//!
+ //! @note
+ //! When you use a container, remember not to make assumptions about its
+ //! representation, unless the documentation gives you those guarantees.
+ //! More details [in the tutorial](@ref tutorial-containers-types).
+ //!
//!
//! Modeled concepts
//! ----------------
diff --git a/boost/hana/fwd/product.hpp b/boost/hana/fwd/product.hpp
index 96bbd77c4e..ff545ceacb 100644
--- a/boost/hana/fwd/product.hpp
+++ b/boost/hana/fwd/product.hpp
@@ -60,7 +60,10 @@ BOOST_HANA_NAMESPACE_BEGIN
struct product_impl : product_impl<T, when<true>> { };
template <typename R>
- struct product_t;
+ struct product_t {
+ template <typename Xs>
+ constexpr decltype(auto) operator()(Xs&& xs) const;
+ };
template <typename R = integral_constant_tag<int>>
constexpr product_t<R> product{};
diff --git a/boost/hana/fwd/range.hpp b/boost/hana/fwd/range.hpp
index 82d0f75232..3fb2a939dc 100644
--- a/boost/hana/fwd/range.hpp
+++ b/boost/hana/fwd/range.hpp
@@ -35,7 +35,8 @@ BOOST_HANA_NAMESPACE_BEGIN
//! The representation of `hana::range` is implementation defined. In
//! particular, one should not take for granted the number and types
//! of template parameters. The proper way to create a `hana::range`
- //! is to use `hana::range_c` or `hana::make_range`.
+ //! is to use `hana::range_c` or `hana::make_range`. More details
+ //! [in the tutorial](@ref tutorial-containers-types).
//!
//!
//! Modeled concepts
diff --git a/boost/hana/fwd/replicate.hpp b/boost/hana/fwd/replicate.hpp
index 4861adabae..842812d692 100644
--- a/boost/hana/fwd/replicate.hpp
+++ b/boost/hana/fwd/replicate.hpp
@@ -65,7 +65,10 @@ BOOST_HANA_NAMESPACE_BEGIN
struct replicate_impl : replicate_impl<M, when<true>> { };
template <typename M>
- struct replicate_t;
+ struct replicate_t {
+ template <typename X, typename N>
+ constexpr auto operator()(X&& x, N const& n) const;
+ };
template <typename M>
constexpr replicate_t<M> replicate{};
diff --git a/boost/hana/fwd/set.hpp b/boost/hana/fwd/set.hpp
index 7312854782..acbcbc7fb5 100644
--- a/boost/hana/fwd/set.hpp
+++ b/boost/hana/fwd/set.hpp
@@ -30,7 +30,8 @@ BOOST_HANA_NAMESPACE_BEGIN
//! In particular, one should not take for granted the order of the
//! template parameters and the presence of any additional constructors
//! or assignment operators than what is documented. The canonical way of
- //! creating a `hana::set` is through `hana::make_set`.
+ //! creating a `hana::set` is through `hana::make_set`. More details
+ //! [in the tutorial](@ref tutorial-containers-types).
//!
//!
//! Modeled concepts
diff --git a/boost/hana/fwd/string.hpp b/boost/hana/fwd/string.hpp
index 80c1622500..8af2e709ba 100644
--- a/boost/hana/fwd/string.hpp
+++ b/boost/hana/fwd/string.hpp
@@ -40,7 +40,8 @@ BOOST_HANA_NAMESPACE_BEGIN
//! In particular, one should not take for granted that the template
//! parameters are `char`s. The proper way to access the contents of
//! a `hana::string` as character constants is to use `hana::unpack`,
- //! `.c_str()` or `hana::to<char const*>`, as documented below.
+ //! `.c_str()` or `hana::to<char const*>`, as documented below. More
+ //! details [in the tutorial](@ref tutorial-containers-types).
//!
//!
//! Modeled concepts
@@ -212,7 +213,8 @@ BOOST_HANA_NAMESPACE_BEGIN
//!
//! This macro is a more convenient alternative to `string_c` for creating
//! compile-time strings. However, since this macro uses a lambda
- //! internally, it can't be used in an unevaluated context.
+ //! internally, it can't be used in an unevaluated context, or where
+ //! a constant expression is expected before C++17.
//!
//!
//! Example
diff --git a/boost/hana/fwd/sum.hpp b/boost/hana/fwd/sum.hpp
index c565ecd7f7..6d7ee537b3 100644
--- a/boost/hana/fwd/sum.hpp
+++ b/boost/hana/fwd/sum.hpp
@@ -69,7 +69,10 @@ BOOST_HANA_NAMESPACE_BEGIN
struct sum_impl : sum_impl<T, when<true>> { };
template <typename M>
- struct sum_t;
+ struct sum_t {
+ template <typename Xs>
+ constexpr decltype(auto) operator()(Xs&& xs) const;
+ };
template <typename M = integral_constant_tag<int>>
constexpr sum_t<M> sum{};
diff --git a/boost/hana/fwd/tap.hpp b/boost/hana/fwd/tap.hpp
index 846c1d00e6..2f3809c1f3 100644
--- a/boost/hana/fwd/tap.hpp
+++ b/boost/hana/fwd/tap.hpp
@@ -55,7 +55,10 @@ BOOST_HANA_NAMESPACE_BEGIN
struct tap_impl : tap_impl<M, when<true>> { };
template <typename M>
- struct tap_t;
+ struct tap_t {
+ template <typename F>
+ constexpr auto operator()(F&& f) const;
+ };
template <typename M>
constexpr tap_t<M> tap{};
diff --git a/boost/hana/fwd/tuple.hpp b/boost/hana/fwd/tuple.hpp
index f51ab9ac22..9ee2e00ace 100644
--- a/boost/hana/fwd/tuple.hpp
+++ b/boost/hana/fwd/tuple.hpp
@@ -32,6 +32,11 @@ BOOST_HANA_NAMESPACE_BEGIN
//! sequence with a key-based access, then you should consider
//! `hana::map` or `hana::set` instead.
//!
+ //! @note
+ //! When you use a container, remember not to make assumptions about its
+ //! representation, unless the documentation gives you those guarantees.
+ //! More details [in the tutorial](@ref tutorial-containers-types).
+ //!
//!
//! Modeled concepts
//! ----------------
diff --git a/boost/hana/fwd/type.hpp b/boost/hana/fwd/type.hpp
index c3c220db78..d087cee166 100644
--- a/boost/hana/fwd/type.hpp
+++ b/boost/hana/fwd/type.hpp
@@ -394,15 +394,13 @@ BOOST_HANA_NAMESPACE_BEGIN
//! @endcode
//!
//! @note
- //! `template_` can't be SFINAE-friendly right now because of
- //! [Core issue 1430][1].
+ //! In a SFINAE context, the expression `template_<f>(type_c<x>...)` is
+ //! valid whenever the expression `f<x...>` is valid.
//!
//!
//! Example
//! -------
//! @include example/type/template.cpp
- //!
- //! [1]: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1430
#ifdef BOOST_HANA_DOXYGEN_INVOKED
template <template <typename ...> class F>
constexpr auto template_ = [](basic_type<T>...) {
@@ -426,6 +424,10 @@ BOOST_HANA_NAMESPACE_BEGIN
//! decltype(metafunction<f>)::apply<x...>::type == f<x...>::type
//! @endcode
//!
+ //! @note
+ //! In a SFINAE context, the expression `metafunction<f>(type_c<x>...)` is
+ //! valid whenever the expression `f<x...>::%type` is valid.
+ //!
//!
//! Example
//! -------
@@ -453,6 +455,10 @@ BOOST_HANA_NAMESPACE_BEGIN
//! decltype(metafunction_class<f>)::apply<x...>::type == f::apply<x...>::type
//! @endcode
//!
+ //! @note
+ //! In a SFINAE context, the expression `metafunction_class<f>(type_c<x>...)`
+ //! is valid whenever the expression `f::apply<x...>::%type` is valid.
+ //!
//!
//! Example
//! -------
@@ -464,9 +470,7 @@ BOOST_HANA_NAMESPACE_BEGIN
};
#else
template <typename F>
- struct metafunction_class_t
- : metafunction_t<F::template apply>
- { };
+ struct metafunction_class_t;
template <typename F>
constexpr metafunction_class_t<F> metafunction_class{};
@@ -498,6 +502,9 @@ BOOST_HANA_NAMESPACE_BEGIN
//! boost/hana/ext/std/integral_constant.hpp header to ensure
//! Hana can interoperate with the result.
//!
+ //! - In a SFINAE context, the expression `integral(f)(t...)` is valid
+ //! whenever the expression `decltype(f(t...))::%type` is valid.
+ //!
//!
//! Example
//! -------
diff --git a/boost/hana/fwd/zero.hpp b/boost/hana/fwd/zero.hpp
index 412614786d..fcbcfcc372 100644
--- a/boost/hana/fwd/zero.hpp
+++ b/boost/hana/fwd/zero.hpp
@@ -35,7 +35,9 @@ BOOST_HANA_NAMESPACE_BEGIN
struct zero_impl : zero_impl<M, when<true>> { };
template <typename M>
- struct zero_t;
+ struct zero_t {
+ constexpr decltype(auto) operator()() const;
+ };
template <typename M>
constexpr zero_t<M> zero{};
diff --git a/boost/hana/lift.hpp b/boost/hana/lift.hpp
index b8ab3431c2..c1d7803788 100644
--- a/boost/hana/lift.hpp
+++ b/boost/hana/lift.hpp
@@ -20,22 +20,22 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN
+ //! @cond
template <typename A>
- struct lift_t {
+ template <typename X>
+ constexpr auto lift_t<A>::operator()(X&& x) const {
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::Applicative<A>::value,
"hana::lift<A> requires 'A' to be an Applicative");
#endif
- template <typename X>
- constexpr auto operator()(X&& x) const {
- using Lift = BOOST_HANA_DISPATCH_IF(lift_impl<A>,
- hana::Applicative<A>::value
- );
+ using Lift = BOOST_HANA_DISPATCH_IF(lift_impl<A>,
+ hana::Applicative<A>::value
+ );
- return Lift::apply(static_cast<X&&>(x));
- }
- };
+ return Lift::apply(static_cast<X&&>(x));
+ }
+ //! @endcond
template <typename A, bool condition>
struct lift_impl<A, when<condition>> : default_ {
diff --git a/boost/hana/map.hpp b/boost/hana/map.hpp
index 8da5012190..7356208bc6 100644
--- a/boost/hana/map.hpp
+++ b/boost/hana/map.hpp
@@ -124,7 +124,7 @@ BOOST_HANA_NAMESPACE_BEGIN
};
template <typename HashTable, typename Storage>
- struct map_impl
+ struct map_impl final
: detail::searchable_operators<map_impl<HashTable, Storage>>
, detail::operators::adl<map_impl<HashTable, Storage>>
{
diff --git a/boost/hana/monadic_fold_left.hpp b/boost/hana/monadic_fold_left.hpp
index e06c405604..3a1e8142a7 100644
--- a/boost/hana/monadic_fold_left.hpp
+++ b/boost/hana/monadic_fold_left.hpp
@@ -27,46 +27,50 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN
+ //! @cond
template <typename M>
- struct monadic_fold_left_t {
+ template <typename Xs, typename State, typename F>
+ constexpr decltype(auto) monadic_fold_left_t<M>::operator()(Xs&& xs, State&& state, F&& f) const {
+ using S = typename hana::tag_of<Xs>::type;
+ using MonadicFoldLeft = BOOST_HANA_DISPATCH_IF(monadic_fold_left_impl<S>,
+ hana::Foldable<S>::value
+ );
+
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::Monad<M>::value,
"hana::monadic_fold_left<M> requires 'M' to be a Monad");
- #endif
- template <typename Xs, typename State, typename F>
- constexpr decltype(auto) operator()(Xs&& xs, State&& state, F&& f) const {
- using S = typename hana::tag_of<Xs>::type;
- using MonadicFoldLeft = BOOST_HANA_DISPATCH_IF(monadic_fold_left_impl<S>,
- hana::Foldable<S>::value
- );
+ static_assert(hana::Foldable<S>::value,
+ "hana::monadic_fold_left<M>(xs, state, f) requires 'xs' to be Foldable");
+ #endif
- #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
- static_assert(hana::Foldable<S>::value,
- "hana::monadic_fold_left<M>(xs, state, f) requires 'xs' to be Foldable");
- #endif
+ return MonadicFoldLeft::template apply<M>(static_cast<Xs&&>(xs),
+ static_cast<State&&>(state),
+ static_cast<F&&>(f));
+ }
+ //! @endcond
- return MonadicFoldLeft::template apply<M>(static_cast<Xs&&>(xs),
- static_cast<State&&>(state),
- static_cast<F&&>(f));
- }
+ //! @cond
+ template <typename M>
+ template <typename Xs, typename F>
+ constexpr decltype(auto) monadic_fold_left_t<M>::operator()(Xs&& xs, F&& f) const {
+ using S = typename hana::tag_of<Xs>::type;
+ using MonadicFoldLeft = BOOST_HANA_DISPATCH_IF(monadic_fold_left_impl<S>,
+ hana::Foldable<S>::value
+ );
- template <typename Xs, typename F>
- constexpr decltype(auto) operator()(Xs&& xs, F&& f) const {
- using S = typename hana::tag_of<Xs>::type;
- using MonadicFoldLeft = BOOST_HANA_DISPATCH_IF(monadic_fold_left_impl<S>,
- hana::Foldable<S>::value
- );
+ #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
+ static_assert(hana::Monad<M>::value,
+ "hana::monadic_fold_left<M> requires 'M' to be a Monad");
- #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
- static_assert(hana::Foldable<S>::value,
- "hana::monadic_fold_left<M>(xs, f) requires 'xs' to be Foldable");
- #endif
+ static_assert(hana::Foldable<S>::value,
+ "hana::monadic_fold_left<M>(xs, f) requires 'xs' to be Foldable");
+ #endif
- return MonadicFoldLeft::template apply<M>(static_cast<Xs&&>(xs),
- static_cast<F&&>(f));
- }
- };
+ return MonadicFoldLeft::template apply<M>(static_cast<Xs&&>(xs),
+ static_cast<F&&>(f));
+ }
+ //! @endcond
namespace detail {
struct foldlM_helper {
diff --git a/boost/hana/monadic_fold_right.hpp b/boost/hana/monadic_fold_right.hpp
index 7026b058c3..c822d1d003 100644
--- a/boost/hana/monadic_fold_right.hpp
+++ b/boost/hana/monadic_fold_right.hpp
@@ -27,45 +27,49 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN
+ //! @cond
template <typename M>
- struct monadic_fold_right_t {
+ template <typename Xs, typename State, typename F>
+ constexpr decltype(auto) monadic_fold_right_t<M>::operator()(Xs&& xs, State&& state, F&& f) const {
+ using S = typename hana::tag_of<Xs>::type;
+ using MonadicFoldRight = BOOST_HANA_DISPATCH_IF(monadic_fold_right_impl<S>,
+ hana::Foldable<S>::value
+ );
+
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::Monad<M>::value,
"hana::monadic_fold_right<M> requires 'M' to be a Monad");
- #endif
- template <typename Xs, typename State, typename F>
- constexpr decltype(auto) operator()(Xs&& xs, State&& state, F&& f) const {
- using S = typename hana::tag_of<Xs>::type;
- using MonadicFoldRight = BOOST_HANA_DISPATCH_IF(monadic_fold_right_impl<S>,
- hana::Foldable<S>::value
- );
+ static_assert(hana::Foldable<S>::value,
+ "hana::monadic_fold_right<M>(xs, state, f) requires 'xs' to be Foldable");
+ #endif
- #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
- static_assert(hana::Foldable<S>::value,
- "hana::monadic_fold_right<M>(xs, state, f) requires 'xs' to be Foldable");
- #endif
+ return MonadicFoldRight::template apply<M>(static_cast<Xs&&>(xs),
+ static_cast<State&&>(state),
+ static_cast<F&&>(f));
+ }
+ //! @endcond
- return MonadicFoldRight::template apply<M>(static_cast<Xs&&>(xs),
- static_cast<State&&>(state),
- static_cast<F&&>(f));
- }
+ //! @cond
+ template <typename M>
+ template <typename Xs, typename F>
+ constexpr decltype(auto) monadic_fold_right_t<M>::operator()(Xs&& xs, F&& f) const {
+ using S = typename hana::tag_of<Xs>::type;
+ using MonadicFoldRight = BOOST_HANA_DISPATCH_IF(monadic_fold_right_impl<S>,
+ hana::Foldable<S>::value
+ );
- template <typename Xs, typename F>
- constexpr decltype(auto) operator()(Xs&& xs, F&& f) const {
- using S = typename hana::tag_of<Xs>::type;
- using MonadicFoldRight = BOOST_HANA_DISPATCH_IF(monadic_fold_right_impl<S>,
- hana::Foldable<S>::value
- );
+ #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
+ static_assert(hana::Monad<M>::value,
+ "hana::monadic_fold_right<M> requires 'M' to be a Monad");
- #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
- static_assert(hana::Foldable<S>::value,
- "hana::monadic_fold_right<M>(xs, f) requires 'xs' to be Foldable");
- #endif
- return MonadicFoldRight::template apply<M>(static_cast<Xs&&>(xs),
- static_cast<F&&>(f));
- }
- };
+ static_assert(hana::Foldable<S>::value,
+ "hana::monadic_fold_right<M>(xs, f) requires 'xs' to be Foldable");
+ #endif
+ return MonadicFoldRight::template apply<M>(static_cast<Xs&&>(xs),
+ static_cast<F&&>(f));
+ }
+ //! @endcond
namespace detail {
struct foldrM_helper {
diff --git a/boost/hana/one.hpp b/boost/hana/one.hpp
index b8d759b8c0..df27b1e834 100644
--- a/boost/hana/one.hpp
+++ b/boost/hana/one.hpp
@@ -23,21 +23,21 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN
+ //! @cond
template <typename R>
- struct one_t {
+ constexpr decltype(auto) one_t<R>::operator()() const {
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::Ring<R>::value,
"hana::one<R>() requires 'R' to be a Ring");
#endif
- constexpr decltype(auto) operator()() const {
- using One = BOOST_HANA_DISPATCH_IF(one_impl<R>,
- hana::Ring<R>::value
- );
+ using One = BOOST_HANA_DISPATCH_IF(one_impl<R>,
+ hana::Ring<R>::value
+ );
- return One::apply();
- }
- };
+ return One::apply();
+ }
+ //! @endcond
template <typename R, bool condition>
struct one_impl<R, when<condition>> : default_ {
diff --git a/boost/hana/product.hpp b/boost/hana/product.hpp
index 8d3bad9fc3..a419b15b40 100644
--- a/boost/hana/product.hpp
+++ b/boost/hana/product.hpp
@@ -23,28 +23,26 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN
+ //! @cond
template <typename R>
- struct product_t {
+ template <typename Xs>
+ constexpr decltype(auto) product_t<R>::operator()(Xs&& xs) const {
+ using S = typename hana::tag_of<Xs>::type;
+ using Product = BOOST_HANA_DISPATCH_IF(product_impl<S>,
+ hana::Foldable<S>::value
+ );
+
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::Ring<R>::value,
"hana::product<R> requires 'R' to be a Ring");
- #endif
-
- template <typename Xs>
- constexpr decltype(auto) operator()(Xs&& xs) const {
- using S = typename hana::tag_of<Xs>::type;
- using Product = BOOST_HANA_DISPATCH_IF(product_impl<S>,
- hana::Foldable<S>::value
- );
- #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
- static_assert(hana::Foldable<S>::value,
- "hana::product<R>(xs) requires 'xs' to be Foldable");
- #endif
+ static_assert(hana::Foldable<S>::value,
+ "hana::product<R>(xs) requires 'xs' to be Foldable");
+ #endif
- return Product::template apply<R>(static_cast<Xs&&>(xs));
- }
- };
+ return Product::template apply<R>(static_cast<Xs&&>(xs));
+ }
+ //! @endcond
template <typename T, bool condition>
struct product_impl<T, when<condition>> : default_ {
diff --git a/boost/hana/replicate.hpp b/boost/hana/replicate.hpp
index f04c4d8a44..3d82712d4f 100644
--- a/boost/hana/replicate.hpp
+++ b/boost/hana/replicate.hpp
@@ -25,28 +25,26 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN
+ //! @cond
template <typename M>
- struct replicate_t {
+ template <typename X, typename N>
+ constexpr auto replicate_t<M>::operator()(X&& x, N const& n) const {
+ using Replicate = BOOST_HANA_DISPATCH_IF(replicate_impl<M>,
+ hana::MonadPlus<M>::value &&
+ hana::IntegralConstant<N>::value
+ );
+
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::MonadPlus<M>::value,
"hana::replicate<M>(x, n) requires 'M' to be a MonadPlus");
- #endif
-
- template <typename X, typename N>
- constexpr auto operator()(X&& x, N const& n) const {
- using Replicate = BOOST_HANA_DISPATCH_IF(replicate_impl<M>,
- hana::MonadPlus<M>::value &&
- hana::IntegralConstant<N>::value
- );
- #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
- static_assert(hana::IntegralConstant<N>::value,
- "hana::replicate<M>(x, n) requires 'n' to be an IntegralConstant");
- #endif
+ static_assert(hana::IntegralConstant<N>::value,
+ "hana::replicate<M>(x, n) requires 'n' to be an IntegralConstant");
+ #endif
- return Replicate::apply(static_cast<X&&>(x), n);
- }
- };
+ return Replicate::apply(static_cast<X&&>(x), n);
+ }
+ //! @endcond
template <typename M, bool condition>
struct replicate_impl<M, when<condition>> : default_ {
diff --git a/boost/hana/set.hpp b/boost/hana/set.hpp
index 58979ed47f..53b4e8ec74 100644
--- a/boost/hana/set.hpp
+++ b/boost/hana/set.hpp
@@ -56,7 +56,7 @@ BOOST_HANA_NAMESPACE_BEGIN
//////////////////////////////////////////////////////////////////////////
//! @cond
template <typename ...Xs>
- struct set
+ struct set final
: detail::operators::adl<set<Xs...>>
, detail::searchable_operators<set<Xs...>>
{
diff --git a/boost/hana/sum.hpp b/boost/hana/sum.hpp
index 5c86dafdde..2b6f6b8219 100644
--- a/boost/hana/sum.hpp
+++ b/boost/hana/sum.hpp
@@ -23,28 +23,26 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN
+ //! @cond
template <typename M>
- struct sum_t {
+ template <typename Xs>
+ constexpr decltype(auto) sum_t<M>::operator()(Xs&& xs) const {
+ using S = typename hana::tag_of<Xs>::type;
+ using Sum = BOOST_HANA_DISPATCH_IF(sum_impl<S>,
+ hana::Foldable<S>::value
+ );
+
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::Monoid<M>::value,
"hana::sum<M> requires 'M' to be a Monoid");
- #endif
-
- template <typename Xs>
- constexpr decltype(auto) operator()(Xs&& xs) const {
- using S = typename hana::tag_of<Xs>::type;
- using Sum = BOOST_HANA_DISPATCH_IF(sum_impl<S>,
- hana::Foldable<S>::value
- );
- #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
- static_assert(hana::Foldable<S>::value,
- "hana::sum<M>(xs) requires 'xs' to be Foldable");
- #endif
+ static_assert(hana::Foldable<S>::value,
+ "hana::sum<M>(xs) requires 'xs' to be Foldable");
+ #endif
- return Sum::template apply<M>(static_cast<Xs&&>(xs));
- }
- };
+ return Sum::template apply<M>(static_cast<Xs&&>(xs));
+ }
+ //! @endcond
template <typename T, bool condition>
struct sum_impl<T, when<condition>> : default_ {
diff --git a/boost/hana/tap.hpp b/boost/hana/tap.hpp
index 7d37318255..332f9ff83d 100644
--- a/boost/hana/tap.hpp
+++ b/boost/hana/tap.hpp
@@ -20,22 +20,22 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN
+ //! @cond
template <typename M>
- struct tap_t {
+ template <typename F>
+ constexpr auto tap_t<M>::operator()(F&& f) const {
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::Monad<M>::value,
"hana::tap<M> requires 'M' to be a Monad");
#endif
- template <typename F>
- constexpr auto operator()(F&& f) const {
- using Tap = BOOST_HANA_DISPATCH_IF(tap_impl<M>,
- hana::Monad<M>::value
- );
+ using Tap = BOOST_HANA_DISPATCH_IF(tap_impl<M>,
+ hana::Monad<M>::value
+ );
- return Tap::apply(static_cast<F&&>(f));
- }
- };
+ return Tap::apply(static_cast<F&&>(f));
+ }
+ //! @endcond
namespace detail {
template <typename M>
diff --git a/boost/hana/tuple.hpp b/boost/hana/tuple.hpp
index 3354a84bee..ae3cba819d 100644
--- a/boost/hana/tuple.hpp
+++ b/boost/hana/tuple.hpp
@@ -75,7 +75,7 @@ BOOST_HANA_NAMESPACE_BEGIN
// tuple
//////////////////////////////////////////////////////////////////////////
template <>
- struct tuple<>
+ struct tuple<> final
: detail::operators::adl<tuple<>>
, detail::iterable_operators<tuple<>>
{
@@ -84,7 +84,7 @@ BOOST_HANA_NAMESPACE_BEGIN
};
template <typename ...Xn>
- struct tuple
+ struct tuple final
: detail::operators::adl<tuple<Xn...>>
, detail::iterable_operators<tuple<Xn...>>
{
diff --git a/boost/hana/type.hpp b/boost/hana/type.hpp
index 80a498753f..b1d3e2a308 100644
--- a/boost/hana/type.hpp
+++ b/boost/hana/type.hpp
@@ -14,6 +14,7 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/bool.hpp>
#include <boost/hana/config.hpp>
+#include <boost/hana/core/when.hpp>
#include <boost/hana/detail/operators/adl.hpp>
#include <boost/hana/detail/operators/comparable.hpp>
#include <boost/hana/fwd/concept/metafunction.hpp>
@@ -152,6 +153,24 @@ BOOST_HANA_NAMESPACE_BEGIN
//////////////////////////////////////////////////////////////////////////
// template_
//////////////////////////////////////////////////////////////////////////
+ // Note: We have to use the very complicated trick below instead of just
+ // mentionning `F<T...>` in a SFINAE-able context because of CWG 1430
+ // (http://www.open-std.org/Jtc1/sc22/wg21/docs/cwg_active.html#1430).
+ namespace template_detail {
+ template <typename ...T> struct args;
+ template <typename ...> using always_void = void;
+
+ template <template <typename ...> class F, typename Args, typename = void>
+ struct specialization_is_valid
+ : std::false_type
+ { };
+
+ template <template <typename ...> class F, typename ...T>
+ struct specialization_is_valid<F, args<T...>, always_void<F<T...>>>
+ : std::true_type
+ { };
+ } // end namespace detail
+
template <template <typename ...> class F>
struct template_t {
template <typename ...T>
@@ -159,7 +178,9 @@ BOOST_HANA_NAMESPACE_BEGIN
using type = F<T...>;
};
- template <typename ...T>
+ template <typename ...T, typename = std::enable_if_t<
+ template_detail::specialization_is_valid<F, template_detail::args<typename T::type...>>::value
+ >>
constexpr auto operator()(T const& ...) const
{ return hana::type<F<typename T::type...>>{}; }
};
@@ -178,6 +199,23 @@ BOOST_HANA_NAMESPACE_BEGIN
};
//////////////////////////////////////////////////////////////////////////
+ // metafunction_class
+ //////////////////////////////////////////////////////////////////////////
+ namespace detail {
+ template <typename F, typename ...T>
+ struct always_first { using type = F; };
+ }
+ template <typename F>
+ struct metafunction_class_t {
+ template <typename ...T>
+ using apply = typename detail::always_first<F, T...>::type::template apply<T...>;
+
+ template <typename ...T>
+ constexpr hana::type<typename detail::always_first<F, T...>::type::template apply<typename T::type...>::type>
+ operator()(T const& ...) const { return {}; }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
// Metafunction
//////////////////////////////////////////////////////////////////////////
template <template <typename ...> class F>
@@ -200,9 +238,10 @@ BOOST_HANA_NAMESPACE_BEGIN
//////////////////////////////////////////////////////////////////////////
template <typename F>
struct integral_t {
- template <typename ...T>
- constexpr auto operator()(T const& ...) const {
- using Result = typename F::template apply<typename T::type...>::type;
+ template <typename ...T, typename Result =
+ typename detail::always_first<F, T...>::type::template apply<typename T::type...>::type
+ >
+ constexpr Result operator()(T const& ...) const {
return Result{};
}
};
diff --git a/boost/hana/version.hpp b/boost/hana/version.hpp
index 70ba6fd9a1..c3a5b3982d 100644
--- a/boost/hana/version.hpp
+++ b/boost/hana/version.hpp
@@ -24,7 +24,7 @@ Distributed under the Boost Software License, Version 1.0.
//! @ingroup group-config
//! Macro expanding to the minor version of the library, i.e. the `y` in `x.y.z`.
-#define BOOST_HANA_MINOR_VERSION 4
+#define BOOST_HANA_MINOR_VERSION 5
//! @ingroup group-config
//! Macro expanding to the patch level of the library, i.e. the `z` in `x.y.z`.
diff --git a/boost/hana/zero.hpp b/boost/hana/zero.hpp
index baba9691f6..317023a1b3 100644
--- a/boost/hana/zero.hpp
+++ b/boost/hana/zero.hpp
@@ -23,21 +23,21 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN
+ //! @cond
template <typename M>
- struct zero_t {
+ constexpr decltype(auto) zero_t<M>::operator()() const {
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::Monoid<M>::value,
"hana::zero<M>() requires 'M' to be a Monoid");
#endif
- constexpr decltype(auto) operator()() const {
- using Zero = BOOST_HANA_DISPATCH_IF(zero_impl<M>,
- hana::Monoid<M>::value
- );
+ using Zero = BOOST_HANA_DISPATCH_IF(zero_impl<M>,
+ hana::Monoid<M>::value
+ );
- return Zero::apply();
- }
- };
+ return Zero::apply();
+ }
+ //! @endcond
template <typename M, bool condition>
struct zero_impl<M, when<condition>> : default_ {