summaryrefslogtreecommitdiff
path: root/boost/hana
diff options
context:
space:
mode:
Diffstat (limited to 'boost/hana')
-rw-r--r--boost/hana/at_key.hpp38
-rw-r--r--boost/hana/basic_tuple.hpp11
-rw-r--r--boost/hana/detail/index_if.hpp68
-rw-r--r--boost/hana/detail/struct_macros.hpp.erb (renamed from boost/hana/detail/struct_macros.erb.hpp)2
-rw-r--r--boost/hana/detail/variadic/foldl1.hpp2
-rw-r--r--boost/hana/detail/variadic/foldr1.hpp2
-rw-r--r--boost/hana/difference.hpp1
-rw-r--r--boost/hana/experimental/view.hpp1
-rw-r--r--boost/hana/ext/std/array.hpp18
-rw-r--r--boost/hana/find_if.hpp78
-rw-r--r--boost/hana/fwd/adjust_if.hpp2
-rw-r--r--boost/hana/fwd/core/tag_of.hpp2
-rw-r--r--boost/hana/fwd/difference.hpp40
-rw-r--r--boost/hana/fwd/index_if.hpp60
-rw-r--r--boost/hana/fwd/intersection.hpp29
-rw-r--r--boost/hana/fwd/map.hpp120
-rw-r--r--boost/hana/fwd/replace_if.hpp2
-rw-r--r--boost/hana/fwd/set.hpp107
-rw-r--r--boost/hana/fwd/symmetric_difference.hpp30
-rw-r--r--boost/hana/fwd/union.hpp33
-rw-r--r--boost/hana/index_if.hpp105
-rw-r--r--boost/hana/map.hpp69
-rw-r--r--boost/hana/pair.hpp16
-rw-r--r--boost/hana/tuple.hpp34
-rw-r--r--boost/hana/version.hpp2
25 files changed, 573 insertions, 299 deletions
diff --git a/boost/hana/at_key.hpp b/boost/hana/at_key.hpp
index 74d45d6d56..e4f2e11255 100644
--- a/boost/hana/at_key.hpp
+++ b/boost/hana/at_key.hpp
@@ -3,6 +3,7 @@
Defines `boost::hana::at_key`.
@copyright Louis Dionne 2013-2017
+@copyright Jason Rice 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)
*/
@@ -24,6 +25,7 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/find_if.hpp>
#include <boost/hana/first.hpp>
#include <boost/hana/functional/on.hpp>
+#include <boost/hana/index_if.hpp>
#include <boost/hana/length.hpp>
#include <boost/hana/optional.hpp>
#include <boost/hana/second.hpp>
@@ -67,42 +69,16 @@ BOOST_HANA_NAMESPACE_BEGIN
return hana::equal(t, u);
}
};
-
- //! @todo This causes an awful duplication of code with `find_if`.
- template <typename Xs, typename Pred, std::size_t i, std::size_t N, bool Done>
- struct advance_until;
-
- template <typename Xs, typename Pred, std::size_t i, std::size_t N>
- struct advance_until<Xs, Pred, i, N, false>
- : advance_until<Xs, Pred, i + 1, N, static_cast<bool>(detail::decay<decltype(
- std::declval<Pred>()(hana::at_c<i>(std::declval<Xs>()))
- )>::type::value)>
- { };
-
- template <typename Xs, typename Pred, std::size_t N>
- struct advance_until<Xs, Pred, N, N, false> {
- template <typename Ys>
- static constexpr auto apply(Ys&&) = delete;
- };
-
- template <typename Xs, typename Pred, std::size_t i, std::size_t N>
- struct advance_until<Xs, Pred, i, N, true> {
- template <typename Ys>
- static constexpr decltype(auto) apply(Ys&& ys) {
- return hana::at_c<i - 1>(static_cast<Ys&&>(ys));
- }
- };
}
template <typename S>
struct at_key_impl<S, when<hana::Sequence<S>::value>> {
template <typename Xs, typename Key>
- static constexpr decltype(auto) apply(Xs&& xs, Key const&) {
- constexpr std::size_t N = decltype(hana::length(xs))::value;
- using Pred = at_key_detail::equal_to<Key>;
- return at_key_detail::advance_until<Xs&&, Pred, 0, N, false>::apply(
- static_cast<Xs&&>(xs)
- );
+ static constexpr decltype(auto) apply(Xs&& xs, Key const& key) {
+ using Result = decltype(hana::index_if(
+ static_cast<Xs&&>(xs), at_key_detail::equal_to<Key>{key}));
+
+ return hana::at(static_cast<Xs&&>(xs), Result{}.value());
}
};
diff --git a/boost/hana/basic_tuple.hpp b/boost/hana/basic_tuple.hpp
index dbc762fb1b..3e624694e0 100644
--- a/boost/hana/basic_tuple.hpp
+++ b/boost/hana/basic_tuple.hpp
@@ -21,15 +21,12 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/fwd/core/make.hpp>
#include <boost/hana/fwd/core/tag_of.hpp>
#include <boost/hana/fwd/drop_front.hpp>
+#include <boost/hana/fwd/integral_constant.hpp>
#include <boost/hana/fwd/is_empty.hpp>
+#include <boost/hana/fwd/length.hpp>
#include <boost/hana/fwd/transform.hpp>
#include <boost/hana/fwd/unpack.hpp>
-#if 0 //! @todo Until we strip down headers, this includes too much
-#include <boost/hana/fwd/integral_constant.hpp>
-#include <boost/hana/fwd/length.hpp>
-#endif
-
#include <cstddef>
#include <type_traits>
#include <utility>
@@ -244,7 +241,6 @@ BOOST_HANA_NAMESPACE_BEGIN
}
};
-#if 0
//////////////////////////////////////////////////////////////////////////
// length
//////////////////////////////////////////////////////////////////////////
@@ -252,10 +248,9 @@ BOOST_HANA_NAMESPACE_BEGIN
struct length_impl<basic_tuple_tag> {
template <typename ...Xn>
static constexpr auto apply(basic_tuple<Xn...> const&) {
- return hana::size_c<sizeof...(Xn)>;
+ return hana::size_t<sizeof...(Xn)>{};
}
};
-#endif
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_BASIC_TUPLE_HPP
diff --git a/boost/hana/detail/index_if.hpp b/boost/hana/detail/index_if.hpp
index 8224f74be8..f643eb76ff 100644
--- a/boost/hana/detail/index_if.hpp
+++ b/boost/hana/detail/index_if.hpp
@@ -3,6 +3,7 @@
Defines `boost::hana::detail::index_if`.
@copyright Louis Dionne 2013-2017
+@copyright Jason Rice 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)
*/
@@ -11,61 +12,44 @@ Distributed under the Boost Software License, Version 1.0.
#define BOOST_HANA_DETAIL_INDEX_IF_HPP
#include <boost/hana/config.hpp>
-#include <boost/hana/core/when.hpp>
+#include <boost/hana/detail/decay.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/optional.hpp>
#include <cstddef>
#include <utility>
BOOST_HANA_NAMESPACE_BEGIN namespace detail {
- template <typename ...T>
- struct pack {
- static constexpr std::size_t length = sizeof...(T);
+ template <std::size_t i, std::size_t N, bool Done>
+ struct index_if_helper;
+
+ template <std::size_t i, std::size_t N>
+ struct index_if_helper<i, N, false> {
+ template <typename Pred, typename X1, typename ...Xs>
+ using f = typename index_if_helper<i + 1, N,
+ static_cast<bool>(detail::decay<decltype(
+ std::declval<Pred>()(std::declval<X1>()))>::type::value)
+ >::template f<Pred, Xs...>;
};
- template <typename T>
- struct make_pack;
-
- template <template <typename...> class Template, typename ...T>
- struct make_pack<Template<T...>> {
- using type = pack<T...>;
- };
-
- template <typename T> struct make_pack<T const> : make_pack<T> { };
- template <typename T> struct make_pack<T&> : make_pack<T> { };
- template <typename T> struct make_pack<T&&> : make_pack<T> { };
-
-
- //! @ingroup group-details
- //! Returns the index of the first element of the `pack<>` that satisfies
- //! the predicate, or the size of the pack if there is no such element.
- //!
- //! @note
- //! The predicate must return an `IntegralConstant` that can be explicitly
- //! converted to `bool`.
- template <typename Pred, typename Ts, typename = when<true>>
- struct index_if;
-
- //! @cond
- template <typename Pred, typename T, typename ...Ts>
- struct index_if<Pred, pack<T, Ts...>, when<static_cast<bool>(decltype(
- std::declval<Pred>()(std::declval<T>())
- )::value)>> {
- static constexpr std::size_t value = 0;
+ template <std::size_t N>
+ struct index_if_helper<N, N, false> {
+ template <typename ...>
+ using f = hana::optional<>;
};
- template <typename Pred, typename T, typename ...Ts>
- struct index_if<Pred, pack<T, Ts...>, when<!static_cast<bool>(decltype(
- std::declval<Pred>()(std::declval<T>())
- )::value)>> {
- static constexpr std::size_t value = 1 + index_if<Pred, pack<Ts...>>::value;
+ template <std::size_t i, std::size_t N>
+ struct index_if_helper<i, N, true> {
+ template <typename ...>
+ using f = hana::optional<hana::size_t<i - 1>>;
};
- template <typename Pred>
- struct index_if<Pred, pack<>> {
- static constexpr std::size_t value = 0;
+ template <typename Pred, typename ...Xs>
+ struct index_if {
+ using type = typename index_if_helper<0, sizeof...(Xs), false>
+ ::template f<Pred, Xs...>;
};
- //! @endcond
} BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_DETAIL_INDEX_IF_HPP
diff --git a/boost/hana/detail/struct_macros.erb.hpp b/boost/hana/detail/struct_macros.hpp.erb
index 2cdc419593..b3675e82af 100644
--- a/boost/hana/detail/struct_macros.erb.hpp
+++ b/boost/hana/detail/struct_macros.hpp.erb
@@ -5,7 +5,7 @@
be controlled with the 'MAX_NUMBER_OF_MEMBERS' variable,
which can be set when calling ERB to generate the header:
- export MAX_NUMBER_OF_MEMBERS=55; erb struct_macros.erb.hpp
+ export MAX_NUMBER_OF_MEMBERS=55; erb struct_macros.hpp.erb
'MAX_NUMBER_OF_MEMBERS' must be <= 62, otherwise an error is triggered.
In case 'MAX_NUMBER_OF_MEMBERS' is not specified, it defaults to 40.
diff --git a/boost/hana/detail/variadic/foldl1.hpp b/boost/hana/detail/variadic/foldl1.hpp
index 320755f7c7..31388028ab 100644
--- a/boost/hana/detail/variadic/foldl1.hpp
+++ b/boost/hana/detail/variadic/foldl1.hpp
@@ -15,6 +15,7 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN namespace detail { namespace variadic {
+ //! @cond
template <unsigned int n, typename = when<true>>
struct foldl1_impl;
@@ -195,6 +196,7 @@ BOOST_HANA_NAMESPACE_BEGIN namespace detail { namespace variadic {
, static_cast<Xn&&>(xn)...);
}
};
+ //! @endcond
struct foldl1_t {
template <typename F, typename X1, typename ...Xn>
diff --git a/boost/hana/detail/variadic/foldr1.hpp b/boost/hana/detail/variadic/foldr1.hpp
index 6221451d90..c7323cdaf8 100644
--- a/boost/hana/detail/variadic/foldr1.hpp
+++ b/boost/hana/detail/variadic/foldr1.hpp
@@ -15,6 +15,7 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN namespace detail { namespace variadic {
+ //! @cond
template <unsigned int n, typename = when<true>>
struct foldr1_impl;
@@ -181,6 +182,7 @@ BOOST_HANA_NAMESPACE_BEGIN namespace detail { namespace variadic {
foldr1_impl<sizeof...(xn) + 1>::apply(f, static_cast<X56&&>(x56), static_cast<Xn&&>(xn)...))))))))))))))))))))))))))))))))))))))))))))))))))))))));
}
};
+ //! @endcond
struct foldr1_t {
template <typename F, typename X1, typename ...Xn>
diff --git a/boost/hana/difference.hpp b/boost/hana/difference.hpp
index 158e727481..d2e2897d6e 100644
--- a/boost/hana/difference.hpp
+++ b/boost/hana/difference.hpp
@@ -14,6 +14,7 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/config.hpp>
#include <boost/hana/core/dispatch.hpp>
+#include <boost/hana/erase_key.hpp>
BOOST_HANA_NAMESPACE_BEGIN
diff --git a/boost/hana/experimental/view.hpp b/boost/hana/experimental/view.hpp
index e9a10b0820..cc2f4c606f 100644
--- a/boost/hana/experimental/view.hpp
+++ b/boost/hana/experimental/view.hpp
@@ -16,6 +16,7 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/detail/decay.hpp>
#include <boost/hana/fold_left.hpp>
#include <boost/hana/functional/compose.hpp>
+#include <boost/hana/functional/on.hpp>
#include <boost/hana/fwd/ap.hpp>
#include <boost/hana/fwd/concat.hpp>
#include <boost/hana/fwd/drop_front.hpp>
diff --git a/boost/hana/ext/std/array.hpp b/boost/hana/ext/std/array.hpp
index 0cb513073c..59bc49cf8d 100644
--- a/boost/hana/ext/std/array.hpp
+++ b/boost/hana/ext/std/array.hpp
@@ -149,13 +149,21 @@ BOOST_HANA_NAMESPACE_BEGIN
//////////////////////////////////////////////////////////////////////////
template <>
struct less_impl<ext::std::array_tag, ext::std::array_tag> {
- template <typename T, typename U>
- static constexpr auto apply(std::array<T, 0> const&, std::array<U, 0> const&)
- { return hana::false_c; }
-
template <typename T, std::size_t n, typename U, std::size_t m>
static constexpr auto apply(std::array<T, n> const& xs, std::array<U, m> const& ys) {
- return detail::lexicographical_compare(&xs[0], &xs[0] + n, &ys[0], &ys[0] + m);
+ // This logic is more complex than it needs to be because we can't
+ // use `.begin()` and `.end()`, which are not constexpr in C++14,
+ // and because `&arr[0]` is UB when the array is empty.
+ if (xs.empty()) {
+ return !ys.empty();
+ } else {
+ if (ys.empty()) {
+ return false;
+ } else {
+ return detail::lexicographical_compare(&xs[0], &xs[0] + n,
+ &ys[0], &ys[0] + m);
+ }
+ }
}
};
BOOST_HANA_NAMESPACE_END
diff --git a/boost/hana/find_if.hpp b/boost/hana/find_if.hpp
index 3c4e07fcb0..de9c3d3eea 100644
--- a/boost/hana/find_if.hpp
+++ b/boost/hana/find_if.hpp
@@ -3,6 +3,7 @@
Defines `boost::hana::find_if`.
@copyright Louis Dionne 2013-2017
+@copyright Jason Rice 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)
*/
@@ -17,19 +18,12 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/bool.hpp>
#include <boost/hana/concept/iterable.hpp>
#include <boost/hana/concept/searchable.hpp>
-#include <boost/hana/concept/sequence.hpp>
#include <boost/hana/concept/struct.hpp>
#include <boost/hana/config.hpp>
#include <boost/hana/core/dispatch.hpp>
-#include <boost/hana/detail/decay.hpp>
-#include <boost/hana/drop_while.hpp>
#include <boost/hana/first.hpp>
-#include <boost/hana/front.hpp>
#include <boost/hana/functional/compose.hpp>
-#include <boost/hana/is_empty.hpp>
-#include <boost/hana/length.hpp>
-#include <boost/hana/not.hpp>
-#include <boost/hana/optional.hpp>
+#include <boost/hana/index_if.hpp>
#include <boost/hana/second.hpp>
#include <boost/hana/transform.hpp>
@@ -62,68 +56,26 @@ BOOST_HANA_NAMESPACE_BEGIN
};
namespace detail {
- template <typename Xs, typename Pred, std::size_t i, std::size_t N, bool Done>
- struct advance_until;
-
- template <typename Xs, typename Pred, std::size_t i, std::size_t N>
- struct advance_until<Xs, Pred, i, N, false>
- : advance_until<Xs, Pred, i + 1, N, static_cast<bool>(detail::decay<decltype(
- std::declval<Pred>()(hana::at_c<i>(std::declval<Xs>()))
- )>::type::value)>
- { };
-
- template <typename Xs, typename Pred, std::size_t N>
- struct advance_until<Xs, Pred, N, N, false> {
- template <typename Ys>
- static constexpr auto apply(Ys&&) {
- return hana::nothing;
- }
- };
+ template <typename Xs>
+ struct partial_at {
+ Xs const& xs;
- template <typename Xs, typename Pred, std::size_t i, std::size_t N>
- struct advance_until<Xs, Pred, i, N, true> {
- template <typename Ys>
- static constexpr auto apply(Ys&& ys) {
- return hana::just(hana::at_c<i - 1>(static_cast<Ys&&>(ys)));
+ template <typename I>
+ constexpr decltype(auto) operator()(I i) const {
+ return hana::at(xs, i);
}
};
}
- template <typename S>
- struct find_if_impl<S, when<Sequence<S>::value>> {
- template <typename Xs, typename Pred>
- static constexpr auto apply(Xs&& xs, Pred&&) {
- constexpr std::size_t N = decltype(hana::length(xs))::value;
- return detail::advance_until<Xs&&, Pred&&, 0, N, false>::apply(
- static_cast<Xs&&>(xs)
- );
- }
- };
-
- template <typename It>
- struct find_if_impl<It, when<hana::Iterable<It>::value && !Sequence<It>::value>> {
- template <typename Xs, typename Pred>
- static constexpr auto find_if_helper(Xs&& xs, Pred&& pred, hana::true_) {
- return hana::just(hana::front(
- hana::drop_while(static_cast<Xs&&>(xs),
- hana::compose(hana::not_, static_cast<Pred&&>(pred)))
- ));
- }
-
- template <typename Xs, typename Pred>
- static constexpr auto find_if_helper(Xs&&, Pred&&, hana::false_) {
- return hana::nothing;
- }
-
+ template <typename Tag>
+ struct find_if_impl<Tag, when<Iterable<Tag>::value>> {
template <typename Xs, typename Pred>
static constexpr auto apply(Xs&& xs, Pred&& pred) {
- constexpr bool found = !decltype(
- hana::is_empty(hana::drop_while(static_cast<Xs&&>(xs),
- hana::compose(hana::not_, static_cast<Pred&&>(pred))))
- )::value;
- return find_if_impl::find_if_helper(static_cast<Xs&&>(xs),
- static_cast<Pred&&>(pred),
- hana::bool_<found>{});
+ using Result = decltype(hana::index_if(
+ static_cast<Xs&&>(xs), static_cast<Pred&&>(pred)));
+
+ return hana::transform(Result{},
+ detail::partial_at<std::decay_t<Xs>>{static_cast<Xs&&>(xs)});
}
};
diff --git a/boost/hana/fwd/adjust_if.hpp b/boost/hana/fwd/adjust_if.hpp
index 017ac03972..3042dc72c9 100644
--- a/boost/hana/fwd/adjust_if.hpp
+++ b/boost/hana/fwd/adjust_if.hpp
@@ -31,7 +31,7 @@ BOOST_HANA_NAMESPACE_BEGIN
//! ---------
//! Given a `Functor` `F` and a `Logical` `Bool`, the signature is
//! \f$
- //! \mathtt{adjust_if} : F(T) \times (T \to Bool) \times (T \to T) \to F(T)
+ //! \mathtt{adjust\_if} : F(T) \times (T \to Bool) \times (T \to T) \to F(T)
//! \f$
//!
//! @param xs
diff --git a/boost/hana/fwd/core/tag_of.hpp b/boost/hana/fwd/core/tag_of.hpp
index bcc4ef8e53..5d490dd717 100644
--- a/boost/hana/fwd/core/tag_of.hpp
+++ b/boost/hana/fwd/core/tag_of.hpp
@@ -57,7 +57,7 @@ BOOST_HANA_NAMESPACE_BEGIN
//! std::is_same<
//! typename fusion::traits::tag_of<T>::type,
//! fusion::traits::tag_of<fusion::vector<>>::type
- //! >{}
+ //! >::value
//! >> {
//! using type = BoostFusionVector;
//! };
diff --git a/boost/hana/fwd/difference.hpp b/boost/hana/fwd/difference.hpp
index 3702f075e0..d96142b5b9 100644
--- a/boost/hana/fwd/difference.hpp
+++ b/boost/hana/fwd/difference.hpp
@@ -15,50 +15,18 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN
- //! Returns the set-theoretic difference of two sets.
- //! @relates hana::set
- //!
- //! Given two sets `xs` and `ys`, `difference(xs, ys)` is a new set
- //! containing all the elements of `xs` that are _not_ contained in `ys`.
- //! For any object `x`, the following holds:
- //! @code
- //! x ^in^ difference(xs, ys) if and only if x ^in^ xs && !(x ^in^ ys)
- //! @endcode
- //!
- //!
- //! @note
- //! This operation is not commutative, i.e. `difference(xs, ys)` is not
- //! necessarily the same as `difference(ys, xs)`. Indeed, consider the
- //! case where `xs` is empty and `ys` isn't. Then, `difference(xs, ys)`
- //! is empty but `difference(ys, xs)` is equal to `ys`. For the symmetric
- //! version of this operation, see `symmetric_difference`.
- //!
- //!
- //! @param xs
- //! A set to remove values from.
- //!
- //! @param ys
- //! The set whose values are removed from `xs`.
- //!
- //!
- //! Example
- //! -------
- //! @include example/difference.cpp
-#ifdef BOOST_HANA_DOXYGEN_INVOKED
- constexpr auto difference = [](auto&& xs, auto&& ys) {
- return tag-dispatched;
- };
-#else
+ // Note: This function is documented per datatype/concept only.
+ //! @cond
template <typename S, typename = void>
struct difference_impl : difference_impl<S, when<true>> { };
+ //! @endcond
struct difference_t {
template <typename Xs, typename Ys>
- constexpr auto operator()(Xs&& xs, Ys&& ys) const;
+ constexpr auto operator()(Xs&&, Ys&&) const;
};
constexpr difference_t difference{};
-#endif
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_FWD_DIFFERENCE_HPP
diff --git a/boost/hana/fwd/index_if.hpp b/boost/hana/fwd/index_if.hpp
new file mode 100644
index 0000000000..59f98f59fa
--- /dev/null
+++ b/boost/hana/fwd/index_if.hpp
@@ -0,0 +1,60 @@
+/*!
+@file
+Forward declares `boost::hana::index_if`.
+
+@copyright Louis Dionne 2013-2017
+@copyright Jason Rice 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_INDEX_IF_HPP
+#define BOOST_HANA_FWD_INDEX_IF_HPP
+
+#include <boost/hana/config.hpp>
+#include <boost/hana/core/when.hpp>
+
+
+BOOST_HANA_NAMESPACE_BEGIN
+ //! Finds the value associated to the first key satisfying a predicate.
+ //! @ingroup group-Iterable
+ //!
+ //! Given an `Iterable` structure `xs` and a predicate `pred`,
+ //! `index_if(xs, pred)` returns a `hana::optional` containing an `IntegralConstant`
+ //! of the index of the first element that satisfies the predicate or nothing
+ //! if no element satisfies the predicate.
+ //!
+ //!
+ //! @param xs
+ //! The structure to be searched.
+ //!
+ //! @param predicate
+ //! A function called as `predicate(x)`, where `x` is an element of the
+ //! `Iterable` structure and returning whether `x` is the element being
+ //! searched for. In the current version of the library, the predicate
+ //! has to return an `IntegralConstant` holding a value that can be
+ //! converted to `bool`.
+ //!
+ //!
+ //! Example
+ //! -------
+ //! @include example/index_if.cpp
+#ifdef BOOST_HANA_DOXYGEN_INVOKED
+ constexpr auto index_if = [](auto&& xs, auto&& predicate) {
+ return tag-dispatched;
+ };
+#else
+ template <typename S, typename = void>
+ struct index_if_impl : index_if_impl<S, when<true>> { };
+
+ struct index_if_t {
+ template <typename Xs, typename Pred>
+ constexpr auto operator()(Xs&& xs, Pred&& pred) const;
+ };
+
+ constexpr index_if_t index_if{};
+#endif
+BOOST_HANA_NAMESPACE_END
+
+#endif // !BOOST_HANA_FWD_INDEX_IF_HPP
+
diff --git a/boost/hana/fwd/intersection.hpp b/boost/hana/fwd/intersection.hpp
index ec9b1daad2..f289dd03fa 100644
--- a/boost/hana/fwd/intersection.hpp
+++ b/boost/hana/fwd/intersection.hpp
@@ -15,39 +15,18 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN
- //! Returns the intersection of two sets.
- //! @relates hana::set
- //!
- //! Given two sets `xs` and `ys`, `intersection(xs, ys)` is a new set
- //! containing exactly those elements that are present both in `xs` and
- //! in `ys`. In other words, the following holds for any object `x`:
- //! @code
- //! x ^in^ intersection(xs, ys) if and only if x ^in^ xs && x ^in^ ys
- //! @endcode
- //!
- //!
- //! @param xs, ys
- //! Two sets to intersect.
- //!
- //!
- //! Example
- //! -------
- //! @include example/intersection.cpp
-#ifdef BOOST_HANA_DOXYGEN_INVOKED
- constexpr auto intersection = [](auto&& xs, auto&& ys) {
- return tag-dispatched;
- };
-#else
+ // Note: This function is documented per datatype/concept only.
+ //! @cond
template <typename S, typename = void>
struct intersection_impl : intersection_impl<S, when<true>> { };
+ //! @endcond
struct intersection_t {
template <typename Xs, typename Ys>
- constexpr auto operator()(Xs&& xs, Ys&& ys) const;
+ constexpr auto operator()(Xs&&, Ys&&) const;
};
constexpr intersection_t intersection{};
-#endif
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_FWD_INTERSECTION_HPP
diff --git a/boost/hana/fwd/map.hpp b/boost/hana/fwd/map.hpp
index bff0b012f0..c00f57195f 100644
--- a/boost/hana/fwd/map.hpp
+++ b/boost/hana/fwd/map.hpp
@@ -255,6 +255,126 @@ BOOST_HANA_NAMESPACE_BEGIN
return tag-dispatched;
};
#endif
+
+ //! Returns the union of two maps.
+ //! @relates hana::map
+ //!
+ //! Given two maps `xs` and `ys`, `hana::union_(xs, ys)` is a new map
+ //! containing all the elements of `xs` and all the elements of `ys`,
+ //! without duplicates. If both `xs` and `ys` contain an element with the
+ //! same `key`, the one in `ys` is taken. Functionally,
+ //! `hana::union_(xs, ys)` is equivalent to
+ //! @code
+ //! hana::fold_left(xs, ys, hana::insert)
+ //! @endcode
+ //!
+ //! @param xs, ys
+ //! The two maps to compute the union of.
+ //!
+ //!
+ //! Example
+ //! -------
+ //! @include example/map/union.cpp
+#ifdef BOOST_HANA_DOXYGEN_INVOKED
+ constexpr auto union_ = [](auto&& xs, auto&& ys) {
+ return tag-dispatched;
+ };
+#endif
+
+ //! Returns the intersection of two maps.
+ //! @relates hana::map
+ //!
+ //! Given two maps `xs` and `ys`, `intersection(xs, ys)` is a new map
+ //! containing exactly those (key, value) pairs from xs, for which key
+ //! is present in `ys`.
+ //! In other words, the following holds for any object `pair(k, v)`:
+ //! @code
+ //! pair(k, v) ^in^ intersection(xs, ys) if and only if (k, v) ^in^ xs && k ^in^ keys(ys)
+ //! @endcode
+ //!
+ //!
+ //! @note
+ //! This function is not commutative, i.e. `intersection(xs, ys)` is not
+ //! necessarily the same as `intersection(ys, xs)`. Indeed, the set of keys
+ //! in `intersection(xs, ys)` is always the same as the set of keys in
+ //! `intersection(ys, xs)`, but the value associated to each key may be
+ //! different. `intersection(xs, ys)` contains values present in `xs`, and
+ //! `intersection(ys, xs)` contains values present in `ys`.
+ //!
+ //!
+ //! @param xs, ys
+ //! Two maps to intersect.
+ //!
+ //!
+ //! Example
+ //! -------
+ //! @include example/map/intersection.cpp
+#ifdef BOOST_HANA_DOXYGEN_INVOKED
+ constexpr auto intersection = [](auto&& xs, auto&& ys) {
+ return tag-dispatched;
+ };
+#endif
+
+ //! Returns the difference of two maps.
+ //! @relates hana::map
+ //!
+ //! Given two maps `xs` and `ys`, `difference(xs, ys)` is a new map
+ //! containing exactly those (key, value) pairs from xs, for which key
+ //! is not present in `keys(ys)`.
+ //! In other words, the following holds for any object `pair(k, v)`:
+ //! @code
+ //! pair(k, v) ^in^ difference(xs, ys) if and only if (k, v) ^in^ xs && k ^not in^ keys(ys)
+ //! @endcode
+ //!
+ //!
+ //! @note
+ //! This function is not commutative, i.e. `difference(xs, ys)` is not
+ //! necessarily the same as `difference(ys, xs)`.
+ //! Indeed, consider the case where `xs` is empty and `ys` isn't.
+ //! In that case, `difference(xs, ys)` is empty, but `difference(ys, xs)`
+ //! is equal to `ys`.
+ //! For symmetric version of this operation, see `symmetric_difference`.
+ //!
+ //!
+ //! @param xs, ys
+ //! Two maps to compute the difference of.
+ //!
+ //!
+ //! Example
+ //! -------
+ //! @include example/map/intersection.cpp
+#ifdef BOOST_HANA_DOXYGEN_INVOKED
+ constexpr auto difference = [](auto&& xs, auto&& ys) {
+ return tag-dispatched;
+ };
+#endif
+
+ //! Returns the symmetric set-theoretic difference of two maps.
+ //! @relates hana::map
+ //!
+ //! Given two sets `xs` and `ys`, `symmetric_difference(xs, ys)` is a new
+ //! map containing all the elements of `xs` whose keys are not contained in `keys(ys)`,
+ //! and all the elements of `ys` whose keys are not contained in `keys(xs)`. The
+ //! symmetric difference of two maps satisfies the following:
+ //! @code
+ //! symmetric_difference(xs, ys) == union_(difference(xs, ys), difference(ys, xs))
+ //! @endcode
+ //!
+ //!
+ //! @param xs, ys
+ //! Two maps to compute the symmetric difference of.
+ //!
+ //!
+ //! Example
+ //! -------
+ //! @include example/map/symmetric_difference.cpp
+#ifdef BOOST_HANA_DOXYGEN_INVOKED
+constexpr auto symmetric_difference = [](auto&& xs, auto&& ys) {
+ return tag-dispatched;
+ };
+#endif
+
+
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_FWD_MAP_HPP
diff --git a/boost/hana/fwd/replace_if.hpp b/boost/hana/fwd/replace_if.hpp
index e3fe882125..48d5b4c15c 100644
--- a/boost/hana/fwd/replace_if.hpp
+++ b/boost/hana/fwd/replace_if.hpp
@@ -24,7 +24,7 @@ BOOST_HANA_NAMESPACE_BEGIN
//! ---------
//! Given `F` a Functor and `Bool` a Logical, the signature is
//! \f$
- //! \mathtt{replace_if} : F(T) \times (T \to Bool) \times T \to F(T)
+ //! \mathtt{replace\_if} : F(T) \times (T \to Bool) \times T \to F(T)
//! \f$
//!
//! @param xs
diff --git a/boost/hana/fwd/set.hpp b/boost/hana/fwd/set.hpp
index 55bd72d248..7312854782 100644
--- a/boost/hana/fwd/set.hpp
+++ b/boost/hana/fwd/set.hpp
@@ -182,9 +182,116 @@ BOOST_HANA_NAMESPACE_BEGIN
};
#endif
+ //! Returns the union of two sets.
+ //! @relates hana::set
+ //!
+ //! Given two sets `xs` and `ys`, `union_(xs, ys)` is a new set containing
+ //! all the elements of `xs` and all the elements of `ys`, without
+ //! duplicates. For any object `x`, the following holds: `x` is in
+ //! `hana::union_(xs, ys)` if and only if `x` is in `xs` or `x` is in `ys`.
+ //!
+ //!
+ //! @param xs, ys
+ //! Two sets to compute the union of.
+ //!
+ //!
+ //! Example
+ //! -------
+ //! @include example/set/union.cpp
+#ifdef BOOST_HANA_DOXYGEN_INVOKED
+ constexpr auto union_ = [](auto&& xs, auto&& ys) {
+ return tag-dispatched;
+ };
+#endif
+
+ //! Returns the intersection of two sets.
+ //! @relates hana::set
+ //!
+ //! Given two sets `xs` and `ys`, `intersection(xs, ys)` is a new set
+ //! containing exactly those elements that are present both in `xs` and
+ //! in `ys`.
+ //! In other words, the following holds for any object `x`:
+ //! @code
+ //! x ^in^ intersection(xs, ys) if and only if x ^in^ xs && x ^in^ ys
+ //! @endcode
+ //!
+ //!
+ //! @param xs, ys
+ //! Two sets to intersect.
+ //!
+ //!
+ //! Example
+ //! -------
+ //! @include example/set/intersection.cpp
+#ifdef BOOST_HANA_DOXYGEN_INVOKED
+ constexpr auto intersection = [](auto&& xs, auto&& ys) {
+ return tag-dispatched;
+ };
+#endif
//! Equivalent to `to<set_tag>`; provided for convenience.
//! @relates hana::set
constexpr auto to_set = to<set_tag>;
+
+ //! Returns the set-theoretic difference of two sets.
+ //! @relates hana::set
+ //!
+ //! Given two sets `xs` and `ys`, `difference(xs, ys)` is a new set
+ //! containing all the elements of `xs` that are _not_ contained in `ys`.
+ //! For any object `x`, the following holds:
+ //! @code
+ //! x ^in^ difference(xs, ys) if and only if x ^in^ xs && !(x ^in^ ys)
+ //! @endcode
+ //!
+ //!
+ //! This operation is not commutative, i.e. `difference(xs, ys)` is not
+ //! necessarily the same as `difference(ys, xs)`. Indeed, consider the
+ //! case where `xs` is empty and `ys` isn't. Then, `difference(xs, ys)`
+ //! is empty but `difference(ys, xs)` is equal to `ys`. For the symmetric
+ //! version of this operation, see `symmetric_difference`.
+ //!
+ //!
+ //! @param xs
+ //! A set param to remove values from.
+ //!
+ //! @param ys
+ //! The set whose values are removed from `xs`.
+ //!
+ //!
+ //! Example
+ //! -------
+ //! @include example/set/difference.cpp
+#ifdef BOOST_HANA_DOXYGEN_INVOKED
+ constexpr auto difference = [](auto&& xs, auto&& ys) {
+ return tag-dispatched;
+};
+#endif
+
+ //! Returns the symmetric set-theoretic difference of two sets.
+ //! @relates hana::set
+ //!
+ //! Given two sets `xs` and `ys`, `symmetric_difference(xs, ys)` is a new
+ //! set containing all the elements of `xs` that are not contained in `ys`,
+ //! and all the elements of `ys` that are not contained in `xs`. The
+ //! symmetric difference of two sets satisfies the following:
+ //! @code
+ //! symmetric_difference(xs, ys) == union_(difference(xs, ys), difference(ys, xs))
+ //! @endcode
+ //!
+ //!
+ //! @param xs, ys
+ //! Two sets to compute the symmetric difference of.
+ //!
+ //!
+ //! Example
+ //! -------
+ //! @include example/set/symmetric_difference.cpp
+#ifdef BOOST_HANA_DOXYGEN_INVOKED
+constexpr auto symmetric_difference = [](auto&& xs, auto&& ys) {
+ return tag-dispatched;
+ };
+#endif
+
+
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_FWD_SET_HPP
diff --git a/boost/hana/fwd/symmetric_difference.hpp b/boost/hana/fwd/symmetric_difference.hpp
index 2908daaeee..2253f167eb 100644
--- a/boost/hana/fwd/symmetric_difference.hpp
+++ b/boost/hana/fwd/symmetric_difference.hpp
@@ -15,40 +15,18 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN
- //! Returns the symmetric set-theoretic difference of two sets.
- //! @relates hana::set
- //!
- //! Given two sets `xs` and `ys`, `symmetric_difference(xs, ys)` is a new
- //! set containing all the elements of `xs` that are not contained in `ys`,
- //! and all the elements of `ys` that are not contained in `xs`. The
- //! symmetric difference of two sets satisfies the following:
- //! @code
- //! symmetric_difference(xs, ys) == union_(difference(xs, ys), difference(ys, xs))
- //! @endcode
- //!
- //!
- //! @param xs, ys
- //! Two sets to compute the symmetric difference of.
- //!
- //!
- //! Example
- //! -------
- //! @include example/symmetric_difference.cpp
-#ifdef BOOST_HANA_DOXYGEN_INVOKED
- constexpr auto symmetric_difference = [](auto&& xs, auto&& ys) {
- return tag-dispatched;
- };
-#else
+ // Note: This function is documented per datatype/concept only.
+ //! @cond
template <typename S, typename = void>
struct symmetric_difference_impl : symmetric_difference_impl<S, when<true>> { };
+ //! @endcond
struct symmetric_difference_t {
template <typename Xs, typename Ys>
- constexpr auto operator()(Xs&& xs, Ys&& ys) const;
+ constexpr auto operator()(Xs&&, Ys&&) const;
};
constexpr symmetric_difference_t symmetric_difference{};
-#endif
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_FWD_SYMMETRIC_DIFFERENCE_HPP
diff --git a/boost/hana/fwd/union.hpp b/boost/hana/fwd/union.hpp
index ccf539221f..5775151888 100644
--- a/boost/hana/fwd/union.hpp
+++ b/boost/hana/fwd/union.hpp
@@ -15,39 +15,18 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN
- //! Returns the union of two sets.
- //! @relates hana::set
- //!
- //! Given two sets `xs` and `ys`, `union_(xs, ys)` is a new set containing
- //! all the elements of `xs` and all the elements of `ys`, without
- //! duplicates. For any object `x`, the following holds:
- //! @code
- //! x ^in^ union_(xs, ys) if and only if x ^in^ xs || x ^in^ ys
- //! @endcode
- //!
- //!
- //! @param xs, ys
- //! Two sets to compute the union of.
- //!
- //!
- //! Example
- //! -------
- //! @include example/union.cpp
-#ifdef BOOST_HANA_DOXYGEN_INVOKED
- constexpr auto union_ = [](auto&& xs, auto&& ys) {
- return tag-dispatched;
- };
-#else
- template <typename S, typename = void>
- struct union_impl : union_impl<S, when<true>> { };
+ // Note: This function is documented per datatype/concept only.
+ //! @cond
+ template <typename T, typename = void>
+ struct union_impl : union_impl<T, when<true>> { };
+ //! @endcond
struct union_t {
template <typename Xs, typename Ys>
- constexpr auto operator()(Xs&& xs, Ys&& ys) const;
+ constexpr auto operator()(Xs&&, Ys&&) const;
};
constexpr union_t union_{};
-#endif
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_FWD_UNION_HPP
diff --git a/boost/hana/index_if.hpp b/boost/hana/index_if.hpp
new file mode 100644
index 0000000000..93ec21c75c
--- /dev/null
+++ b/boost/hana/index_if.hpp
@@ -0,0 +1,105 @@
+/*!
+@file
+Defines `boost::hana::index_if`.
+
+@copyright Louis Dionne 2013-2017
+@copyright Jason Rice 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_INDEX_IF_HPP
+#define BOOST_HANA_INDEX_IF_HPP
+
+#include <boost/hana/concept/foldable.hpp>
+#include <boost/hana/concept/iterable.hpp>
+#include <boost/hana/config.hpp>
+#include <boost/hana/detail/decay.hpp>
+#include <boost/hana/detail/index_if.hpp>
+#include <boost/hana/fwd/at.hpp>
+#include <boost/hana/fwd/basic_tuple.hpp>
+#include <boost/hana/fwd/index_if.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/length.hpp>
+#include <boost/hana/optional.hpp>
+
+#include <cstddef>
+#include <utility>
+
+
+BOOST_HANA_NAMESPACE_BEGIN
+ //! @cond
+ template <typename Xs, typename Pred>
+ constexpr auto index_if_t::operator()(Xs&& xs, Pred&& pred) const {
+ using S = typename hana::tag_of<Xs>::type;
+ using IndexIf = BOOST_HANA_DISPATCH_IF(index_if_impl<S>,
+ hana::Iterable<S>::value
+ );
+
+ #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
+ static_assert(hana::Iterable<S>::value,
+ "hana::index_if(xs, pred) requires 'xs' to be a Iterable");
+ #endif
+
+ return IndexIf::apply(static_cast<Xs&&>(xs), static_cast<Pred&&>(pred));
+ }
+ //! @endcond
+
+ namespace detail {
+ template <std::size_t i, std::size_t N, bool Done>
+ struct iterate_while;
+
+ template <std::size_t i, std::size_t N>
+ struct iterate_while<i, N, false> {
+ template <typename Xs, typename Pred>
+ using f = typename iterate_while<i + 1, N,
+ static_cast<bool>(detail::decay<decltype(
+ std::declval<Pred>()(
+ hana::at(std::declval<Xs>(), hana::size_c<i>)))>::type::value)
+ >::template f<Xs, Pred>;
+ };
+
+ template <std::size_t N>
+ struct iterate_while<N, N, false> {
+ template <typename Xs, typename Pred>
+ using f = hana::optional<>;
+ };
+
+ template <std::size_t i, std::size_t N>
+ struct iterate_while<i, N, true> {
+ template <typename Xs, typename Pred>
+ using f = hana::optional<hana::size_t<i - 1>>;
+ };
+ }
+
+ template <typename Tag>
+ struct index_if_impl<Tag, when<Foldable<Tag>::value>> {
+ template <typename Xs, typename Pred>
+ static constexpr auto apply(Xs const& xs, Pred const&)
+ -> typename detail::iterate_while<0,
+ decltype(hana::length(xs))::value, false>
+ ::template f<Xs, Pred>
+ { return {}; }
+ };
+
+ template <typename It>
+ struct index_if_impl<It, when<!Foldable<It>::value>> {
+ template <typename Xs, typename Pred>
+ static constexpr auto apply(Xs const&, Pred const&)
+ -> typename detail::iterate_while<hana::size_c<0>,
+ static_cast<std::size_t>(-1), false>
+ ::template f<Xs, Pred>
+ { return {}; }
+ };
+
+ // basic_tuple is implemented here to solve circular dependency issues.
+ template <>
+ struct index_if_impl<basic_tuple_tag> {
+ template <typename ...Xs, typename Pred>
+ static constexpr auto apply(basic_tuple<Xs...> const&, Pred const&)
+ -> typename detail::index_if<Pred, Xs...>::type
+ { return {}; }
+ };
+BOOST_HANA_NAMESPACE_END
+
+#endif // !BOOST_HANA_INDEX_IF_HPP
diff --git a/boost/hana/map.hpp b/boost/hana/map.hpp
index cccf6cf3b9..8da5012190 100644
--- a/boost/hana/map.hpp
+++ b/boost/hana/map.hpp
@@ -40,9 +40,12 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/functional/partial.hpp>
#include <boost/hana/fwd/any_of.hpp>
#include <boost/hana/fwd/at_key.hpp>
+#include <boost/hana/fwd/difference.hpp>
#include <boost/hana/fwd/erase_key.hpp>
+#include <boost/hana/fwd/intersection.hpp>
#include <boost/hana/fwd/is_subset.hpp>
#include <boost/hana/fwd/keys.hpp>
+#include <boost/hana/fwd/union.hpp>
#include <boost/hana/insert.hpp>
#include <boost/hana/integral_constant.hpp>
#include <boost/hana/keys.hpp>
@@ -53,6 +56,7 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/unpack.hpp>
#include <boost/hana/value.hpp>
+
#include <cstddef>
#include <type_traits>
#include <utility>
@@ -480,6 +484,71 @@ BOOST_HANA_NAMESPACE_BEGIN
};
//////////////////////////////////////////////////////////////////////////
+ // union_
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct union_impl<map_tag> {
+ template <typename Xs, typename Ys>
+ static constexpr auto apply(Xs&& xs, Ys&& ys) {
+ return hana::fold_left(static_cast<Xs&&>(xs), static_cast<Ys&&>(ys),
+ hana::insert);
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // intersection_
+ //////////////////////////////////////////////////////////////////////////
+ namespace detail {
+ template <typename Ys>
+ struct map_insert_if_contains {
+ Ys const& ys;
+
+ // Second template param will be pair
+ // Get its key and check if it exists, if it does, insert key, value pair.
+ template <typename Result, typename Pair>
+ static constexpr auto helper(Result&& result, Pair&& pair, hana::true_) {
+ return hana::insert(static_cast<Result&&>(result), static_cast<Pair&&>(pair));
+ }
+
+ template <typename Result, typename Pair>
+ static constexpr auto helper(Result&& result, Pair&&, hana::false_) {
+ return static_cast<Result&&>(result);
+ }
+
+ template <typename Result, typename Pair>
+ constexpr auto operator()(Result&& result, Pair&& pair) const {
+ constexpr bool keep = hana::value<decltype(hana::contains(ys, hana::first(pair)))>();
+ return map_insert_if_contains::helper(static_cast<Result&&>(result),
+ static_cast<Pair&&>(pair),
+ hana::bool_c<keep>);
+ }
+ };
+ }
+
+ template <>
+ struct intersection_impl<map_tag> {
+ template <typename Xs, typename Ys>
+ static constexpr auto apply(Xs&& xs, Ys const& ys) {
+ return hana::fold_left(static_cast<Xs&&>(xs), hana::make_map(),
+ detail::map_insert_if_contains<Ys>{ys});
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // difference
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct difference_impl<map_tag> {
+ template <typename Xs, typename Ys>
+ static constexpr auto apply(Xs&& xs, Ys&& ys) {
+ return hana::fold_left(
+ hana::keys(static_cast<Ys&&>(ys)),
+ static_cast<Xs&&>(xs),
+ hana::erase_key);
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////////
// Foldable
//////////////////////////////////////////////////////////////////////////
template <>
diff --git a/boost/hana/pair.hpp b/boost/hana/pair.hpp
index 75cd9e287b..35ff857269 100644
--- a/boost/hana/pair.hpp
+++ b/boost/hana/pair.hpp
@@ -79,8 +79,8 @@ BOOST_HANA_NAMESPACE_BEGIN
BOOST_HANA_TT_IS_CONVERTIBLE(U const&, Second)
>::type>
constexpr pair(pair<T, U> const& other)
- : detail::ebo<detail::pix<0>, First>(detail::ebo_get<detail::pix<0>>(other))
- , detail::ebo<detail::pix<1>, Second>(detail::ebo_get<detail::pix<1>>(other))
+ : detail::ebo<detail::pix<0>, First>(hana::first(other))
+ , detail::ebo<detail::pix<1>, Second>(hana::second(other))
{ }
template <typename T, typename U, typename = typename std::enable_if<
@@ -90,8 +90,8 @@ BOOST_HANA_NAMESPACE_BEGIN
BOOST_HANA_TT_IS_CONVERTIBLE(U&&, Second)
>::type>
constexpr pair(pair<T, U>&& other)
- : detail::ebo<detail::pix<0>, First>(static_cast<T&&>(detail::ebo_get<detail::pix<0>>(other)))
- , detail::ebo<detail::pix<1>, Second>(static_cast<U&&>(detail::ebo_get<detail::pix<1>>(other)))
+ : detail::ebo<detail::pix<0>, First>(hana::first(static_cast<pair<T, U>&&>(other)))
+ , detail::ebo<detail::pix<1>, Second>(hana::second(static_cast<pair<T, U>&&>(other)))
{ }
@@ -101,8 +101,8 @@ BOOST_HANA_NAMESPACE_BEGIN
BOOST_HANA_TT_IS_ASSIGNABLE(Second&, U const&)
>::type>
constexpr pair& operator=(pair<T, U> const& other) {
- detail::ebo_get<detail::pix<0>>(*this) = detail::ebo_get<detail::pix<0>>(other);
- detail::ebo_get<detail::pix<1>>(*this) = detail::ebo_get<detail::pix<1>>(other);
+ hana::first(*this) = hana::first(other);
+ hana::second(*this) = hana::second(other);
return *this;
}
@@ -111,8 +111,8 @@ BOOST_HANA_NAMESPACE_BEGIN
BOOST_HANA_TT_IS_ASSIGNABLE(Second&, U&&)
>::type>
constexpr pair& operator=(pair<T, U>&& other) {
- detail::ebo_get<detail::pix<0>>(*this) = static_cast<T&&>(detail::ebo_get<detail::pix<0>>(other));
- detail::ebo_get<detail::pix<1>>(*this) = static_cast<U&&>(detail::ebo_get<detail::pix<1>>(other));
+ hana::first(*this) = hana::first(static_cast<pair<T, U>&&>(other));
+ hana::second(*this) = hana::second(static_cast<pair<T, U>&&>(other));
return *this;
}
diff --git a/boost/hana/tuple.hpp b/boost/hana/tuple.hpp
index cab5eaa4d6..3354a84bee 100644
--- a/boost/hana/tuple.hpp
+++ b/boost/hana/tuple.hpp
@@ -3,6 +3,7 @@
Defines `boost::hana::tuple`.
@copyright Louis Dionne 2013-2017
+@copyright Jason Rice 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)
*/
@@ -27,7 +28,7 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/fwd/at.hpp>
#include <boost/hana/fwd/core/make.hpp>
#include <boost/hana/fwd/drop_front.hpp>
-#include <boost/hana/fwd/find_if.hpp>
+#include <boost/hana/fwd/index_if.hpp>
#include <boost/hana/fwd/is_empty.hpp>
#include <boost/hana/fwd/length.hpp>
#include <boost/hana/fwd/optional.hpp>
@@ -140,7 +141,7 @@ BOOST_HANA_NAMESPACE_BEGIN
// The three following constructors are required to make sure that
// the tuple(Yn&&...) constructor is _not_ preferred over the copy
// constructor for unary tuples containing a type that is constructible
- // from tuple<...>. See test/tuple/trap_construct.cpp
+ // from tuple<...>. See test/tuple/cnstr.trap.cpp
template <typename ...dummy, typename = typename std::enable_if<
detail::fast_and<BOOST_HANA_TT_IS_CONSTRUCTIBLE(Xn, Xn const&, dummy...)...>::value
>::type>
@@ -283,6 +284,14 @@ BOOST_HANA_NAMESPACE_BEGIN
return hana::at_c<n>(static_cast<tuple<Xs...>&&>(xs).storage_);
}
+ template <>
+ struct index_if_impl<tuple_tag> {
+ template <typename ...Xs, typename Pred>
+ static constexpr auto apply(tuple<Xs...> const&, Pred const&)
+ -> typename detail::index_if<Pred, Xs...>::type
+ { return {}; }
+ };
+
//////////////////////////////////////////////////////////////////////////
// Sequence
//////////////////////////////////////////////////////////////////////////
@@ -298,27 +307,6 @@ BOOST_HANA_NAMESPACE_BEGIN
tuple<typename detail::decay<Xs>::type...> apply(Xs&& ...xs)
{ return {static_cast<Xs&&>(xs)...}; }
};
-
- template <>
- struct find_if_impl<tuple_tag> {
- template <std::size_t index, typename Xs>
- static constexpr auto helper(Xs&&, hana::true_) {
- return hana::nothing;
- }
-
- template <std::size_t index, typename Xs>
- static constexpr auto helper(Xs&& xs, hana::false_) {
- return hana::just(hana::at_c<index>(static_cast<Xs&&>(xs)));
- }
-
- template <typename Xs, typename Pred>
- static constexpr auto apply(Xs&& xs, Pred&&) {
- using Pack = typename detail::make_pack<Xs>::type;
- constexpr std::size_t index = detail::index_if<Pred&&, Pack>::value;
- constexpr std::size_t len = Pack::length;
- return helper<index>(static_cast<Xs&&>(xs), hana::bool_c<index == len>);
- }
- };
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_TUPLE_HPP
diff --git a/boost/hana/version.hpp b/boost/hana/version.hpp
index 2699bfd0e5..160170a51f 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 1
+#define BOOST_HANA_MINOR_VERSION 2
//! @ingroup group-config
//! Macro expanding to the patch level of the library, i.e. the `z` in `x.y.z`.