summaryrefslogtreecommitdiff
path: root/boost/hof
diff options
context:
space:
mode:
Diffstat (limited to 'boost/hof')
-rw-r--r--boost/hof/alias.hpp219
-rw-r--r--boost/hof/always.hpp174
-rw-r--r--boost/hof/apply.hpp252
-rw-r--r--boost/hof/apply_eval.hpp156
-rw-r--r--boost/hof/arg.hpp126
-rw-r--r--boost/hof/capture.hpp189
-rw-r--r--boost/hof/combine.hpp126
-rw-r--r--boost/hof/compose.hpp169
-rw-r--r--boost/hof/config.hpp201
-rw-r--r--boost/hof/construct.hpp302
-rw-r--r--boost/hof/decay.hpp68
-rw-r--r--boost/hof/decorate.hpp217
-rw-r--r--boost/hof/detail/and.hpp55
-rw-r--r--boost/hof/detail/callable_base.hpp65
-rw-r--r--boost/hof/detail/can_be_called.hpp121
-rw-r--r--boost/hof/detail/compressed_pair.hpp130
-rw-r--r--boost/hof/detail/constexpr_deduce.hpp74
-rw-r--r--boost/hof/detail/delegate.hpp107
-rw-r--r--boost/hof/detail/forward.hpp37
-rw-r--r--boost/hof/detail/holder.hpp27
-rw-r--r--boost/hof/detail/intrinsics.hpp113
-rw-r--r--boost/hof/detail/join.hpp43
-rw-r--r--boost/hof/detail/make.hpp31
-rw-r--r--boost/hof/detail/move.hpp24
-rw-r--r--boost/hof/detail/noexcept.hpp19
-rw-r--r--boost/hof/detail/pp.hpp93
-rw-r--r--boost/hof/detail/recursive_constexpr_depth.hpp19
-rw-r--r--boost/hof/detail/remove_rvalue_reference.hpp26
-rw-r--r--boost/hof/detail/result_of.hpp82
-rw-r--r--boost/hof/detail/result_type.hpp43
-rw-r--r--boost/hof/detail/seq.hpp46
-rw-r--r--boost/hof/detail/static_const_var.hpp68
-rw-r--r--boost/hof/detail/unpack_tuple.hpp98
-rw-r--r--boost/hof/detail/unwrap.hpp29
-rw-r--r--boost/hof/detail/using.hpp21
-rw-r--r--boost/hof/eval.hpp86
-rw-r--r--boost/hof/first_of.hpp244
-rw-r--r--boost/hof/fix.hpp242
-rw-r--r--boost/hof/flip.hpp107
-rw-r--r--boost/hof/flow.hpp166
-rw-r--r--boost/hof/fold.hpp171
-rw-r--r--boost/hof/function.hpp90
-rw-r--r--boost/hof/function_param_limit.hpp57
-rw-r--r--boost/hof/identity.hpp72
-rw-r--r--boost/hof/if.hpp143
-rw-r--r--boost/hof/implicit.hpp155
-rw-r--r--boost/hof/indirect.hpp133
-rw-r--r--boost/hof/infix.hpp200
-rw-r--r--boost/hof/is_invocable.hpp72
-rw-r--r--boost/hof/is_unpackable.hpp115
-rw-r--r--boost/hof/lambda.hpp244
-rw-r--r--boost/hof/lazy.hpp299
-rw-r--r--boost/hof/lift.hpp110
-rw-r--r--boost/hof/limit.hpp142
-rw-r--r--boost/hof/match.hpp121
-rw-r--r--boost/hof/mutable.hpp68
-rw-r--r--boost/hof/pack.hpp423
-rw-r--r--boost/hof/partial.hpp292
-rw-r--r--boost/hof/pipable.hpp215
-rw-r--r--boost/hof/placeholders.hpp468
-rw-r--r--boost/hof/proj.hpp265
-rw-r--r--boost/hof/protect.hpp80
-rw-r--r--boost/hof/repeat.hpp162
-rw-r--r--boost/hof/repeat_while.hpp181
-rw-r--r--boost/hof/result.hpp135
-rw-r--r--boost/hof/returns.hpp249
-rw-r--r--boost/hof/reveal.hpp385
-rw-r--r--boost/hof/reverse_fold.hpp173
-rw-r--r--boost/hof/rotate.hpp101
-rw-r--r--boost/hof/static.hpp97
-rw-r--r--boost/hof/tap.hpp83
-rw-r--r--boost/hof/unpack.hpp181
-rw-r--r--boost/hof/unpack_sequence.hpp71
-rw-r--r--boost/hof/version.hpp16
74 files changed, 10184 insertions, 0 deletions
diff --git a/boost/hof/alias.hpp b/boost/hof/alias.hpp
new file mode 100644
index 0000000000..c95cbaf754
--- /dev/null
+++ b/boost/hof/alias.hpp
@@ -0,0 +1,219 @@
+/*=============================================================================
+ Copyright (c) 2015 Paul Fultz II
+ alias.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_ALIAS_H
+#define BOOST_HOF_GUARD_ALIAS_H
+
+#include <boost/hof/returns.hpp>
+#include <boost/hof/detail/delegate.hpp>
+#include <boost/hof/detail/move.hpp>
+#include <boost/hof/detail/holder.hpp>
+#include <boost/hof/config.hpp>
+
+/// alias
+/// =====
+///
+/// Description
+/// -----------
+///
+/// The `alias` class wraps a type with a new type that can be tagged by the
+/// user. This allows defining extra attributes about the type outside of the
+/// type itself. There are three different ways the value can be stored: as a
+/// member variable, by inheritance, or as a static member variable. The value
+/// can be retrieved uniformily using the `alias_value` function.
+///
+/// Synopsis
+/// --------
+///
+/// // Alias the type using a member variable
+/// template<class T, class Tag=void>
+/// class alias;
+///
+/// // Alias the type by inheriting
+/// template<class T, class Tag=void>
+/// class alias_inherit;
+///
+/// // Alias the type using a static variable
+/// template<class T, class Tag=void>
+/// class alias_static;
+///
+/// // Retrieve tag from alias
+/// template<class Alias>
+/// class alias_tag;
+///
+/// // Check if type has a certian tag
+/// template<class T, class Tag>
+/// class has_tag;
+///
+/// // Retrieve value from alias
+/// template<class Alias>
+/// constexpr auto alias_value(Alias&&);
+///
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4579)
+#endif
+
+namespace boost { namespace hof {
+
+template<class T>
+struct alias_tag;
+
+template<class T, class Tag, class=void>
+struct has_tag
+: std::false_type
+{};
+
+template<class T, class Tag>
+struct has_tag<T, Tag, typename detail::holder<
+ typename alias_tag<T>::type
+>::type>
+: std::is_same<typename alias_tag<T>::type, Tag>
+{};
+
+namespace detail {
+
+template<class T>
+constexpr T& lvalue(T& x) noexcept
+{
+ return x;
+}
+
+template<class T>
+constexpr const T& lvalue(const T& x) noexcept
+{
+ return x;
+}
+
+}
+
+#define BOOST_HOF_UNARY_PERFECT_FOREACH(m) \
+ m(const&, boost::hof::detail::lvalue) \
+ m(&, boost::hof::detail::lvalue) \
+ m(&&, boost::hof::move) \
+
+template<class T, class Tag=void>
+struct alias
+{
+ T value;
+ BOOST_HOF_DELEGATE_CONSTRUCTOR(alias, T, value)
+};
+
+#define BOOST_HOF_DETAIL_ALIAS_GET_VALUE(ref, move) \
+template<class Tag, class T, class... Ts> \
+constexpr auto alias_value(alias<T, Tag> ref a, Ts&&...) BOOST_HOF_RETURNS(move(a.value))
+BOOST_HOF_UNARY_PERFECT_FOREACH(BOOST_HOF_DETAIL_ALIAS_GET_VALUE)
+
+template<class T, class Tag>
+struct alias_tag<alias<T, Tag>>
+{ typedef Tag type; };
+
+
+template<class T, class Tag=void>
+struct alias_inherit
+#if (defined(__GNUC__) && !defined (__clang__))
+: std::conditional<(std::is_class<T>::value), T, alias<T>>::type
+#else
+: T
+#endif
+{
+ BOOST_HOF_INHERIT_CONSTRUCTOR(alias_inherit, T)
+};
+
+#define BOOST_HOF_DETAIL_ALIAS_INHERIT_GET_VALUE(ref, move) \
+template<class Tag, class T, class... Ts, class=typename std::enable_if<(BOOST_HOF_IS_CLASS(T))>::type> \
+constexpr T ref alias_value(alias_inherit<T, Tag> ref a, Ts&&...) BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(move(a)) \
+{ \
+ return move(a); \
+}
+BOOST_HOF_UNARY_PERFECT_FOREACH(BOOST_HOF_DETAIL_ALIAS_INHERIT_GET_VALUE)
+
+template<class T, class Tag>
+struct alias_tag<alias_inherit<T, Tag>>
+{ typedef Tag type; };
+
+namespace detail {
+
+template<class T, class Tag>
+struct alias_static_storage
+{
+#ifdef _MSC_VER
+ // Since we disable the error for 4579 on MSVC, which leaves the static
+ // member unitialized at runtime, it is, therefore, only safe to use this
+ // class on types that are empty with constructors that have no possible
+ // side effects.
+ static_assert(BOOST_HOF_IS_EMPTY(T) &&
+ BOOST_HOF_IS_LITERAL(T) &&
+ BOOST_HOF_IS_DEFAULT_CONSTRUCTIBLE(T), "In-class initialization is not yet implemented on MSVC");
+#endif
+ static constexpr T value = T();
+};
+
+template<class T, class Tag>
+constexpr T alias_static_storage<T, Tag>::value;
+
+}
+
+template<class T, class Tag=void>
+struct alias_static
+{
+ template<class... Ts, BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(T, Ts...)>
+ constexpr alias_static(Ts&&...) noexcept
+ {}
+};
+
+template<class Tag, class T, class... Ts>
+constexpr const T& alias_value(const alias_static<T, Tag>&, Ts&&...) noexcept
+{
+ return detail::alias_static_storage<T, Tag>::value;
+}
+
+template<class T, class Tag>
+struct alias_tag<alias_static<T, Tag>>
+{ typedef Tag type; };
+
+namespace detail {
+
+template<class T, class Tag>
+struct alias_try_inherit
+: std::conditional<(BOOST_HOF_IS_CLASS(T) && !BOOST_HOF_IS_FINAL(T) && !BOOST_HOF_IS_POLYMORPHIC(T)),
+ alias_inherit<T, Tag>,
+ alias<T, Tag>
+>
+{};
+
+#if BOOST_HOF_HAS_EBO
+template<class T, class Tag>
+struct alias_empty
+: std::conditional<(BOOST_HOF_IS_EMPTY(T)),
+ typename alias_try_inherit<T, Tag>::type,
+ alias<T, Tag>
+>
+{};
+#else
+template<class T, class Tag>
+struct alias_empty
+: std::conditional<
+ BOOST_HOF_IS_EMPTY(T) &&
+ BOOST_HOF_IS_LITERAL(T) &&
+ BOOST_HOF_IS_DEFAULT_CONSTRUCTIBLE(T),
+ alias_static<T, Tag>,
+ alias<T, Tag>
+>
+{};
+#endif
+
+}
+
+}} // namespace boost::hof
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif
diff --git a/boost/hof/always.hpp b/boost/hof/always.hpp
new file mode 100644
index 0000000000..647796fd35
--- /dev/null
+++ b/boost/hof/always.hpp
@@ -0,0 +1,174 @@
+/*=============================================================================
+ Copyright (c) 2014 Paul Fultz II
+ always.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FUNCTION_ALWAYS_H
+#define BOOST_HOF_GUARD_FUNCTION_ALWAYS_H
+
+#include <boost/hof/detail/delegate.hpp>
+#include <boost/hof/detail/unwrap.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+
+/// always
+/// ======
+///
+/// Description
+/// -----------
+///
+/// The `always` function returns a function object that will always return
+/// the value given to it, no matter what parameters are passed to the
+/// function object. The nullary version(i.e. `always(void)`) will return
+/// `void`. On compilers, that don't support constexpr functions returning
+/// `void`, a private empty type is returned instead. This return type is
+/// specified as `BOOST_HOF_ALWAYS_VOID_RETURN`.
+///
+/// Synopsis
+/// --------
+///
+/// template<class T>
+/// constexpr auto always(T value);
+///
+/// template<class T>
+/// constexpr auto always(void);
+///
+///
+/// Semantics
+/// ---------
+///
+/// assert(always(x)(xs...) == x);
+///
+/// Requirements
+/// ------------
+///
+/// T must be:
+///
+/// * CopyConstructible
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <algorithm>
+/// #include <cassert>
+/// using namespace boost::hof;
+///
+/// int main() {
+/// int ten = 10;
+/// assert( always(ten)(1,2,3,4,5) == 10 );
+/// }
+///
+/// // Count all
+/// template<class Iterator, class T>
+/// auto count(Iterator first, Iterator last)
+/// {
+/// return std::count_if(first, last, always(true));
+/// }
+///
+
+
+#ifndef BOOST_HOF_NO_CONSTEXPR_VOID
+#if defined(__clang__) && BOOST_HOF_HAS_RELAXED_CONSTEXPR
+#define BOOST_HOF_NO_CONSTEXPR_VOID 0
+#else
+#define BOOST_HOF_NO_CONSTEXPR_VOID 1
+#endif
+#endif
+
+namespace boost { namespace hof { namespace always_detail {
+
+template<class T, class=void>
+struct always_base
+{
+ T x;
+
+ BOOST_HOF_DELEGATE_CONSTRUCTOR(always_base, T, x)
+
+ typedef typename detail::unwrap_reference<T>::type result_type;
+
+ template<class... As>
+ constexpr result_type
+ operator()(As&&...) const
+ noexcept(std::is_reference<result_type>::value || BOOST_HOF_IS_NOTHROW_COPY_CONSTRUCTIBLE(result_type))
+ {
+ return this->x;
+ }
+};
+
+template<class T>
+struct always_base<T, typename std::enable_if<!BOOST_HOF_IS_EMPTY(T)>::type>
+{
+ T x;
+
+ constexpr always_base(T xp) noexcept(BOOST_HOF_IS_NOTHROW_COPY_CONSTRUCTIBLE(T))
+ : x(xp)
+ {}
+
+ typedef typename detail::unwrap_reference<T>::type result_type;
+
+ template<class... As>
+ constexpr result_type
+ operator()(As&&...) const
+ noexcept(std::is_reference<result_type>::value || BOOST_HOF_IS_NOTHROW_COPY_CONSTRUCTIBLE(result_type))
+ {
+ return this->x;
+ }
+};
+
+#if BOOST_HOF_NO_CONSTEXPR_VOID
+#define BOOST_HOF_ALWAYS_VOID_RETURN boost::hof::always_detail::always_base<void>::void_
+#else
+#define BOOST_HOF_ALWAYS_VOID_RETURN void
+#endif
+
+template<>
+struct always_base<void>
+{
+
+ constexpr always_base() noexcept
+ {}
+
+ struct void_ {};
+
+ template<class... As>
+ constexpr BOOST_HOF_ALWAYS_VOID_RETURN
+ operator()(As&&...) const noexcept
+ {
+#if BOOST_HOF_NO_CONSTEXPR_VOID
+ return void_();
+#endif
+ }
+};
+
+struct always_f
+{
+ template<class T>
+ constexpr always_detail::always_base<T> operator()(T x) const noexcept(BOOST_HOF_IS_NOTHROW_COPY_CONSTRUCTIBLE(T))
+ {
+ return always_detail::always_base<T>(x);
+ }
+
+ constexpr always_detail::always_base<void> operator()() const noexcept
+ {
+ return always_detail::always_base<void>();
+ }
+};
+
+struct always_ref_f
+{
+ template<class T>
+ constexpr always_detail::always_base<T&> operator()(T& x) const noexcept
+ {
+ return always_detail::always_base<T&>(x);
+ }
+};
+
+}
+BOOST_HOF_DECLARE_STATIC_VAR(always, always_detail::always_f);
+BOOST_HOF_DECLARE_STATIC_VAR(always_ref, always_detail::always_ref_f);
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/apply.hpp b/boost/hof/apply.hpp
new file mode 100644
index 0000000000..3605a015e9
--- /dev/null
+++ b/boost/hof/apply.hpp
@@ -0,0 +1,252 @@
+/*=============================================================================
+ Copyright (c) 2015 Paul Fultz II
+ apply.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_APPLY_H
+#define BOOST_HOF_GUARD_APPLY_H
+
+/// apply
+/// =====
+///
+/// Description
+/// -----------
+///
+/// The `apply` function calls the function given to it with its arguments.
+///
+/// Synopsis
+/// --------
+///
+/// template<class F, class... Ts>
+/// constexpr auto apply(F&& f, Ts&&... xs);
+///
+/// Semantics
+/// ---------
+///
+/// assert(apply(f)(xs...) == f(xs...));
+/// assert(fold(apply, f)(x, y, z) == f(x)(y)(z));
+///
+/// Requirements
+/// ------------
+///
+/// F must be:
+///
+/// * [Invocable](Invocable)
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+///
+/// struct sum_f
+/// {
+/// template<class T, class U>
+/// T operator()(T x, U y) const
+/// {
+/// return x+y;
+/// }
+/// };
+///
+/// int main() {
+/// assert(boost::hof::apply(sum_f(), 1, 2) == 3);
+/// }
+///
+
+#include <boost/hof/detail/result_of.hpp>
+#include <boost/hof/detail/forward.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4003)
+#endif
+
+#define BOOST_HOF_DETAIL_FOREACH_QUAL(m, data) \
+ m(, data) \
+ m(const, data) \
+ m(volatile, data) \
+ m(const volatile, data)
+
+namespace boost { namespace hof {
+
+namespace detail {
+#if BOOST_HOF_HAS_MANUAL_DEDUCTION || BOOST_HOF_NO_EXPRESSION_SFINAE
+struct apply_mem_fn
+{
+ template<class...>
+ struct convertible_args;
+
+ template<class T, class U, class=void>
+ struct is_convertible_args
+ : std::false_type
+ {};
+
+ template<class... Ts, class... Us>
+ struct is_convertible_args<
+ convertible_args<Ts...>,
+ convertible_args<Us...>,
+ typename std::enable_if<(
+ sizeof...(Ts) == sizeof...(Us)
+ )>::type
+ >
+ : and_<std::is_convertible<Ts, Us>...>
+ {};
+
+ template<class From, class To>
+ struct is_compatible
+ : std::is_convertible<
+ typename std::add_pointer<typename std::remove_reference<From>::type>::type,
+ typename std::add_pointer<typename std::remove_reference<To>::type>::type
+ >
+ {};
+
+#define BOOST_HOF_APPLY_MEM_FN_CALL(cv, data) \
+ template <class R, class Base, class Derived, class... Ts, class... Us, class=typename std::enable_if<and_< \
+ is_compatible<Derived, cv Base>, \
+ is_convertible_args<convertible_args<Us...>, convertible_args<Ts...>> \
+ >::value>::type> \
+ constexpr R operator()(R (Base::*mf)(Ts...) cv, Derived&& ref, Us &&... xs) const \
+ BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT((BOOST_HOF_FORWARD(Derived)(ref).*mf)(BOOST_HOF_FORWARD(Us)(xs)...)) \
+ { \
+ return (BOOST_HOF_FORWARD(Derived)(ref).*mf)(BOOST_HOF_FORWARD(Us)(xs)...); \
+ }
+ BOOST_HOF_DETAIL_FOREACH_QUAL(BOOST_HOF_APPLY_MEM_FN_CALL, ~)
+};
+
+struct apply_mem_data
+{
+ template<class T, class R>
+ struct match_qualifier
+ { typedef R type; };
+
+#define BOOST_HOF_APPLY_MEM_DATA_MATCH(cv, ref) \
+ template<class T, class R> \
+ struct match_qualifier<cv T ref, R> \
+ : match_qualifier<T, cv R ref> \
+ {};
+
+ BOOST_HOF_DETAIL_FOREACH_QUAL(BOOST_HOF_APPLY_MEM_DATA_MATCH,&)
+ BOOST_HOF_DETAIL_FOREACH_QUAL(BOOST_HOF_APPLY_MEM_DATA_MATCH,&&)
+
+ template <class Base, class R, class Derived, class=typename std::enable_if<(
+ std::is_base_of<Base, typename std::decay<Derived>::type>::value
+ )>::type>
+ constexpr typename match_qualifier<Derived, R>::type
+ operator()(R Base::*pmd, Derived&& ref) const noexcept
+ {
+ return BOOST_HOF_FORWARD(Derived)(ref).*pmd;
+ }
+};
+
+template<class T, class U=decltype(*std::declval<T>())>
+struct apply_deref
+{ typedef U type; };
+
+#endif
+
+struct apply_f
+{
+#if BOOST_HOF_HAS_MANUAL_DEDUCTION || BOOST_HOF_NO_EXPRESSION_SFINAE
+ template<class F, class T, class... Ts, class=typename std::enable_if<(
+ std::is_member_function_pointer<typename std::decay<F>::type>::value
+ )>::type>
+ constexpr BOOST_HOF_SFINAE_MANUAL_RESULT(apply_mem_fn, id_<F>, id_<T>, id_<Ts>...)
+ operator()(F&& f, T&& obj, Ts&&... xs) const BOOST_HOF_SFINAE_MANUAL_RETURNS
+ (
+ apply_mem_fn()(f, BOOST_HOF_FORWARD(T)(obj), BOOST_HOF_FORWARD(Ts)(xs)...)
+ );
+
+ template<class F, class T, class... Ts, class U=typename apply_deref<T>::type, class=typename std::enable_if<(
+ std::is_member_function_pointer<typename std::decay<F>::type>::value
+ )>::type>
+ constexpr BOOST_HOF_SFINAE_MANUAL_RESULT(apply_mem_fn, id_<F>, id_<U>, id_<Ts>...)
+ operator()(F&& f, T&& obj, Ts&&... xs) const BOOST_HOF_SFINAE_MANUAL_RETURNS
+ (
+ apply_mem_fn()(f, *BOOST_HOF_FORWARD(T)(obj), BOOST_HOF_FORWARD(Ts)(xs)...)
+ );
+
+ template<class F, class T, class... Ts, class=typename std::enable_if<(
+ std::is_member_function_pointer<typename std::decay<F>::type>::value
+ )>::type>
+ constexpr BOOST_HOF_SFINAE_MANUAL_RESULT(apply_mem_fn, id_<F>, id_<T&>, id_<Ts>...)
+ operator()(F&& f, const std::reference_wrapper<T>& ref, Ts&&... xs) const BOOST_HOF_SFINAE_MANUAL_RETURNS
+ (
+ apply_mem_fn()(f, ref.get(), BOOST_HOF_FORWARD(Ts)(xs)...)
+ );
+
+ template<class F, class T, class=typename std::enable_if<(
+ std::is_member_object_pointer<typename std::decay<F>::type>::value
+ )>::type>
+ constexpr BOOST_HOF_SFINAE_MANUAL_RESULT(apply_mem_data, id_<F>, id_<T>)
+ operator()(F&& f, T&& obj) const BOOST_HOF_SFINAE_MANUAL_RETURNS
+ (
+ apply_mem_data()(f, BOOST_HOF_FORWARD(T)(obj))
+ );
+
+ template<class F, class T, class U=typename apply_deref<T>::type, class=typename std::enable_if<(
+ std::is_member_object_pointer<typename std::decay<F>::type>::value
+ )>::type>
+ constexpr BOOST_HOF_SFINAE_MANUAL_RESULT(apply_mem_data, id_<F>, id_<U>)
+ operator()(F&& f, T&& obj) const BOOST_HOF_SFINAE_MANUAL_RETURNS
+ (
+ apply_mem_data()(f, *BOOST_HOF_FORWARD(T)(obj))
+ );
+
+ template<class F, class T, class=typename std::enable_if<(
+ std::is_member_object_pointer<typename std::decay<F>::type>::value
+ )>::type>
+ constexpr BOOST_HOF_SFINAE_MANUAL_RESULT(apply_mem_data, id_<F>, id_<T&>)
+ operator()(F&& f, const std::reference_wrapper<T>& ref) const BOOST_HOF_SFINAE_MANUAL_RETURNS
+ (
+ apply_mem_data()(f, ref.get())
+ );
+
+#else
+
+ template <class Base, class T, class Derived>
+ constexpr auto operator()(T Base::*pmd, Derived&& ref) const
+ BOOST_HOF_RETURNS(BOOST_HOF_FORWARD(Derived)(ref).*pmd);
+
+ template <class PMD, class Pointer>
+ constexpr auto operator()(PMD&& pmd, Pointer&& ptr) const
+ BOOST_HOF_RETURNS((*BOOST_HOF_FORWARD(Pointer)(ptr)).*BOOST_HOF_FORWARD(PMD)(pmd));
+
+ template <class Base, class T, class Derived>
+ constexpr auto operator()(T Base::*pmd, const std::reference_wrapper<Derived>& ref) const
+ BOOST_HOF_RETURNS(ref.get().*pmd);
+
+ template <class Base, class T, class Derived, class... Args>
+ constexpr auto operator()(T Base::*pmf, Derived&& ref, Args&&... args) const
+ BOOST_HOF_RETURNS((BOOST_HOF_FORWARD(Derived)(ref).*pmf)(BOOST_HOF_FORWARD(Args)(args)...));
+
+ template <class PMF, class Pointer, class... Args>
+ constexpr auto operator()(PMF&& pmf, Pointer&& ptr, Args&&... args) const
+ BOOST_HOF_RETURNS(((*BOOST_HOF_FORWARD(Pointer)(ptr)).*BOOST_HOF_FORWARD(PMF)(pmf))(BOOST_HOF_FORWARD(Args)(args)...));
+
+ template <class Base, class T, class Derived, class... Args>
+ constexpr auto operator()(T Base::*pmf, const std::reference_wrapper<Derived>& ref, Args&&... args) const
+ BOOST_HOF_RETURNS((ref.get().*pmf)(BOOST_HOF_FORWARD(Args)(args)...));
+
+#endif
+ template<class F, class... Ts>
+ constexpr BOOST_HOF_SFINAE_MANUAL_RESULT(F, id_<Ts>...)
+ operator()(F&& f, Ts&&... xs) const BOOST_HOF_SFINAE_MANUAL_RETURNS
+ (
+ f(BOOST_HOF_FORWARD(Ts)(xs)...)
+ );
+};
+
+}
+
+BOOST_HOF_DECLARE_STATIC_VAR(apply, detail::apply_f);
+
+}} // namespace boost::hof
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif
diff --git a/boost/hof/apply_eval.hpp b/boost/hof/apply_eval.hpp
new file mode 100644
index 0000000000..2c0c265abf
--- /dev/null
+++ b/boost/hof/apply_eval.hpp
@@ -0,0 +1,156 @@
+/*=============================================================================
+ Copyright (c) 2015 Paul Fultz II
+ apply_eval.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_APPLY_EVAL_H
+#define BOOST_HOF_GUARD_APPLY_EVAL_H
+
+/// apply_eval
+/// ==========
+///
+/// Description
+/// -----------
+///
+/// The `apply_eval` function work like [`apply`](/include/boost/hof/apply), except it calls
+/// [`eval`](/include/boost/hof/eval) on each of its arguments. Each [`eval`](/include/boost/hof/eval) call is
+/// always ordered from left-to-right.
+///
+/// Synopsis
+/// --------
+///
+/// template<class F, class... Ts>
+/// constexpr auto apply_eval(F&& f, Ts&&... xs);
+///
+/// Semantics
+/// ---------
+///
+/// assert(apply_eval(f)(xs...) == f(eval(xs)...));
+///
+/// Requirements
+/// ------------
+///
+/// F must be:
+///
+/// * [ConstInvocable](ConstInvocable)
+///
+/// Ts must be:
+///
+/// * [EvaluatableFunctionObject](EvaluatableFunctionObject)
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+///
+/// struct sum_f
+/// {
+/// template<class T, class U>
+/// T operator()(T x, U y) const
+/// {
+/// return x+y;
+/// }
+/// };
+///
+/// int main() {
+/// assert(boost::hof::apply_eval(sum_f(), []{ return 1; }, []{ return 2; }) == 3);
+/// }
+///
+
+#include <boost/hof/config.hpp>
+#include <boost/hof/returns.hpp>
+#include <boost/hof/detail/forward.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+#include <boost/hof/apply.hpp>
+#include <boost/hof/eval.hpp>
+
+#if BOOST_HOF_NO_ORDERED_BRACE_INIT
+#include <boost/hof/pack.hpp>
+#include <boost/hof/capture.hpp>
+#endif
+
+namespace boost { namespace hof {
+
+namespace detail {
+
+#if BOOST_HOF_NO_ORDERED_BRACE_INIT
+template<class R, class F, class Pack>
+constexpr R eval_ordered(const F& f, Pack&& p)
+{
+ return p(f);
+}
+
+template<class R, class F, class Pack, class T, class... Ts>
+constexpr R eval_ordered(const F& f, Pack&& p, T&& x, Ts&&... xs)
+{
+ return boost::hof::detail::eval_ordered<R>(f, boost::hof::pack_join(BOOST_HOF_FORWARD(Pack)(p), boost::hof::pack_forward(boost::hof::eval(x))), BOOST_HOF_FORWARD(Ts)(xs)...);
+}
+#else
+template<class R>
+struct eval_helper
+{
+ R result;
+
+ template<class F, class... Ts>
+ constexpr eval_helper(const F& f, Ts&&... xs) : result(boost::hof::apply(f, BOOST_HOF_FORWARD(Ts)(xs)...))
+ {}
+};
+
+template<>
+struct eval_helper<void>
+{
+ int x;
+ template<class F, class... Ts>
+ constexpr eval_helper(const F& f, Ts&&... xs) : x((boost::hof::apply(f, BOOST_HOF_FORWARD(Ts)(xs)...), 0))
+ {}
+};
+#endif
+
+struct apply_eval_f
+{
+ template<class F, class... Ts, class R=decltype(
+ boost::hof::apply(std::declval<const F&>(), boost::hof::eval(std::declval<Ts>())...)
+ ),
+ class=typename std::enable_if<(!std::is_void<R>::value)>::type
+ >
+ constexpr R operator()(const F& f, Ts&&... xs) const BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(boost::hof::apply(f, boost::hof::eval(BOOST_HOF_FORWARD(Ts)(xs))...))
+ {
+ return
+#if BOOST_HOF_NO_ORDERED_BRACE_INIT
+ boost::hof::detail::eval_ordered<R>
+ (f, boost::hof::pack(), BOOST_HOF_FORWARD(Ts)(xs)...);
+#else
+ boost::hof::detail::eval_helper<R>
+ {f, boost::hof::eval(BOOST_HOF_FORWARD(Ts)(xs))...}.result;
+#endif
+ }
+
+ template<class F, class... Ts, class R=decltype(
+ boost::hof::apply(std::declval<const F&>(), boost::hof::eval(std::declval<Ts>())...)
+ ),
+ class=typename std::enable_if<(std::is_void<R>::value)>::type
+ >
+ constexpr typename detail::holder<Ts...>::type
+ operator()(const F& f, Ts&&... xs) const BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(boost::hof::apply(f, boost::hof::eval(BOOST_HOF_FORWARD(Ts)(xs))...))
+ {
+ return (typename detail::holder<Ts...>::type)
+#if BOOST_HOF_NO_ORDERED_BRACE_INIT
+ boost::hof::detail::eval_ordered<R>
+ (f, boost::hof::pack(), BOOST_HOF_FORWARD(Ts)(xs)...);
+#else
+ boost::hof::detail::eval_helper<R>
+ {f, boost::hof::eval(BOOST_HOF_FORWARD(Ts)(xs))...};
+#endif
+ }
+};
+
+}
+
+BOOST_HOF_DECLARE_STATIC_VAR(apply_eval, detail::apply_eval_f);
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/arg.hpp b/boost/hof/arg.hpp
new file mode 100644
index 0000000000..332789da6e
--- /dev/null
+++ b/boost/hof/arg.hpp
@@ -0,0 +1,126 @@
+/*=============================================================================
+ Copyright (c) 2014 Paul Fultz II
+ arg.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FUNCTION_ARGS_H
+#define BOOST_HOF_GUARD_FUNCTION_ARGS_H
+
+#include <boost/hof/detail/seq.hpp>
+#include <boost/hof/returns.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+#include <utility>
+
+/// arg
+/// ===
+///
+/// Description
+/// -----------
+///
+/// The `arg` function returns a function object that returns the Nth argument
+/// passed to it. It actually starts at 1, so it is not the zero-based index
+/// of the argument.
+///
+/// Synopsis
+/// --------
+///
+/// template<class IntegralConstant>
+/// constexpr auto arg(IntegralConstant);
+///
+/// template<std::size_t N, class... Ts>
+/// constexpr auto arg_c(Ts&&...);
+///
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+/// using namespace boost::hof;
+///
+/// int main() {
+/// assert(arg(std::integral_constant<int, 3>())(1,2,3,4,5) == 3);
+/// }
+///
+
+namespace boost { namespace hof {
+
+namespace detail {
+
+template<class T>
+struct perfect_ref
+{
+ typedef T type;
+ typedef typename std::remove_reference<T>::type value_type;
+ T&& value;
+ constexpr perfect_ref(value_type& x) noexcept
+ : value(BOOST_HOF_FORWARD(T)(x))
+ {}
+};
+
+template<std::size_t N>
+struct ignore
+{
+ template<class T>
+ constexpr ignore(T&&...) noexcept
+ {}
+};
+
+template<std::size_t... N>
+struct args_at
+{
+ template<class T, class... Ts>
+ constexpr auto operator()(ignore<N>..., T x, Ts...) const
+ BOOST_HOF_RETURNS(BOOST_HOF_FORWARD(typename T::type)(x.value));
+};
+
+template<std::size_t... N>
+constexpr args_at<N...> make_args_at(seq<N...>) noexcept
+{
+ return {};
+}
+
+template<std::size_t N, class... Ts>
+constexpr auto get_args(Ts&&... xs) BOOST_HOF_RETURNS
+(
+ boost::hof::detail::make_args_at(typename gens<N>::type())(nullptr, BOOST_HOF_RETURNS_CONSTRUCT(perfect_ref<Ts>)(xs)...)
+);
+
+template<class T, T N>
+struct make_args_f
+{
+ template<class... Ts, class=typename std::enable_if<(N <= sizeof...(Ts))>::type>
+ constexpr auto operator()(Ts&&... xs) const BOOST_HOF_RETURNS
+ (
+ boost::hof::detail::get_args<N>(BOOST_HOF_FORWARD(Ts)(xs)...)
+ );
+};
+
+struct arg_f
+{
+ template<class IntegralConstant>
+ constexpr make_args_f<std::size_t, IntegralConstant::value> operator()(IntegralConstant) const noexcept
+ {
+ return make_args_f<std::size_t, IntegralConstant::value>();
+ }
+};
+
+}
+#if BOOST_HOF_HAS_VARIABLE_TEMPLATES
+template<std::size_t N>
+BOOST_HOF_STATIC_CONSTEXPR detail::make_args_f<std::size_t, N> arg_c = {};
+#else
+template<std::size_t N, class... Ts>
+constexpr auto arg_c(Ts&&... xs) BOOST_HOF_RETURNS
+(
+ boost::hof::detail::get_args<N>(BOOST_HOF_FORWARD(Ts)(xs)...)
+);
+#endif
+
+BOOST_HOF_DECLARE_STATIC_VAR(arg, detail::arg_f);
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/capture.hpp b/boost/hof/capture.hpp
new file mode 100644
index 0000000000..8ddeb779ec
--- /dev/null
+++ b/boost/hof/capture.hpp
@@ -0,0 +1,189 @@
+/*=============================================================================
+ Copyright (c) 2015 Paul Fultz II
+ capture.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_CAPTURE_H
+#define BOOST_HOF_GUARD_CAPTURE_H
+
+#include <boost/hof/detail/callable_base.hpp>
+#include <boost/hof/detail/compressed_pair.hpp>
+#include <boost/hof/reveal.hpp>
+#include <boost/hof/pack.hpp>
+#include <boost/hof/always.hpp>
+#include <boost/hof/detail/move.hpp>
+#include <boost/hof/detail/result_type.hpp>
+
+/// capture
+/// =======
+///
+/// Description
+/// -----------
+///
+/// The `capture` function decorator is used to capture values in a function.
+/// It provides more flexibility in capturing than the lambda capture list in
+/// C++. It provides a way to do move and perfect capturing. The values
+/// captured are prepended to the argument list of the function that will be
+/// called.
+///
+/// Synopsis
+/// --------
+///
+/// // Capture by decaying each value
+/// template<class... Ts>
+/// constexpr auto capture(Ts&&... xs);
+///
+/// // Capture lvalues by reference and rvalue reference by reference
+/// template<class... Ts>
+/// constexpr auto capture_forward(Ts&&... xs);
+///
+/// // Capture lvalues by reference and rvalues by value.
+/// template<class... Ts>
+/// constexpr auto capture_basic(Ts&&... xs);
+///
+/// Semantics
+/// ---------
+///
+/// assert(capture(xs...)(f)(ys...) == f(xs..., ys...));
+///
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+///
+/// struct sum_f
+/// {
+/// template<class T, class U>
+/// T operator()(T x, U y) const
+/// {
+/// return x+y;
+/// }
+/// };
+///
+/// int main() {
+/// auto add_one = boost::hof::capture(1)(sum_f());
+/// assert(add_one(2) == 3);
+/// }
+///
+
+namespace boost { namespace hof {
+
+namespace detail {
+
+template<class F, class Pack>
+struct capture_invoke : detail::compressed_pair<detail::callable_base<F>, Pack>, detail::function_result_type<F>
+{
+ typedef capture_invoke fit_rewritable1_tag;
+ typedef detail::compressed_pair<detail::callable_base<F>, Pack> base;
+ BOOST_HOF_INHERIT_CONSTRUCTOR(capture_invoke, base)
+ template<class... Ts>
+ constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const noexcept
+ {
+ return this->first(xs...);
+ }
+
+ template<class... Ts>
+ constexpr const Pack& get_pack(Ts&&...xs) const noexcept
+ {
+ return this->second(xs...);
+ }
+
+ template<class Failure, class... Ts>
+ struct unpack_capture_failure
+ {
+ template<class... Us>
+ struct apply
+ {
+ typedef typename Failure::template of<Us..., Ts...> type;
+ };
+ };
+
+ struct capture_failure
+ {
+ template<class Failure>
+ struct apply
+ {
+ template<class... Ts>
+ struct of
+ : Pack::template apply<unpack_capture_failure<Failure, Ts...>>::type
+ {};
+ };
+ };
+
+ struct failure
+ : failure_map<capture_failure, detail::callable_base<F>>
+ {};
+
+ BOOST_HOF_RETURNS_CLASS(capture_invoke);
+
+ template<class... Ts>
+ constexpr BOOST_HOF_SFINAE_RESULT
+ (
+ typename result_of<decltype(boost::hof::pack_join),
+ id_<const Pack&>,
+ result_of<decltype(boost::hof::pack_forward), id_<Ts>...>
+ >::type,
+ id_<detail::callable_base<F>&&>
+ )
+ operator()(Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS
+ (
+ boost::hof::pack_join
+ (
+ BOOST_HOF_MANGLE_CAST(const Pack&)(BOOST_HOF_CONST_THIS->get_pack(xs...)),
+ boost::hof::pack_forward(BOOST_HOF_FORWARD(Ts)(xs)...)
+ )
+ (BOOST_HOF_RETURNS_C_CAST(detail::callable_base<F>&&)(BOOST_HOF_CONST_THIS->base_function(xs...)))
+ );
+};
+
+template<class Pack>
+struct capture_pack : Pack
+{
+ BOOST_HOF_INHERIT_CONSTRUCTOR(capture_pack, Pack);
+
+ BOOST_HOF_RETURNS_CLASS(capture_pack);
+
+ // TODO: Should use rvalue ref qualifier
+ template<class F>
+ constexpr auto operator()(F f) const BOOST_HOF_SFINAE_RETURNS
+ (
+ capture_invoke<F, Pack>(BOOST_HOF_RETURNS_STATIC_CAST(F&&)(f),
+ BOOST_HOF_RETURNS_C_CAST(Pack&&)(
+ BOOST_HOF_RETURNS_STATIC_CAST(const Pack&)(*boost::hof::always(BOOST_HOF_CONST_THIS)(f))
+ )
+ )
+ );
+};
+
+struct make_capture_pack_f
+{
+ template<class Pack>
+ constexpr capture_pack<Pack> operator()(Pack p) const
+ BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(capture_pack<Pack>, Pack&&)
+ {
+ return capture_pack<Pack>(static_cast<Pack&&>(p));
+ }
+};
+
+template<class F>
+struct capture_f
+{
+ template<class... Ts>
+ constexpr auto operator()(Ts&&... xs) const BOOST_HOF_RETURNS
+ (
+ BOOST_HOF_RETURNS_CONSTRUCT(make_capture_pack_f)()(BOOST_HOF_RETURNS_CONSTRUCT(F)()(BOOST_HOF_FORWARD(Ts)(xs)...))
+ );
+};
+}
+
+BOOST_HOF_DECLARE_STATIC_VAR(capture_basic, detail::capture_f<detail::pack_basic_f>);
+BOOST_HOF_DECLARE_STATIC_VAR(capture_forward, detail::capture_f<detail::pack_forward_f>);
+BOOST_HOF_DECLARE_STATIC_VAR(capture, detail::capture_f<detail::pack_f>);
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/combine.hpp b/boost/hof/combine.hpp
new file mode 100644
index 0000000000..97c40b0ec4
--- /dev/null
+++ b/boost/hof/combine.hpp
@@ -0,0 +1,126 @@
+/*=============================================================================
+ Copyright (c) 2015 Paul Fultz II
+ combine.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_COMBINE_H
+#define BOOST_HOF_GUARD_COMBINE_H
+
+/// combine
+/// =======
+///
+/// Description
+/// -----------
+///
+/// The `combine` function adaptor combines several functions together with
+/// their arguments. It essentially zips each function with an argument before
+/// calling the main function.
+///
+/// Synopsis
+/// --------
+///
+/// template<class F, class... Gs>
+/// constexpr combine_adaptor<F, Gs...> combine(F f, Gs... gs);
+///
+/// Semantics
+/// ---------
+///
+/// assert(combine(f, gs...)(xs...) == f(gs(xs)...));
+///
+/// Requirements
+/// ------------
+///
+/// F and Gs must be:
+///
+/// * [ConstInvocable](ConstInvocable)
+/// * MoveConstructible
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+/// #include <tuple>
+/// #include <utility>
+///
+/// int main() {
+/// auto f = boost::hof::combine(
+/// boost::hof::construct<std::tuple>(),
+/// boost::hof::capture(1)(boost::hof::construct<std::pair>()),
+/// boost::hof::capture(2)(boost::hof::construct<std::pair>()));
+/// assert(f(3, 7) == std::make_tuple(std::make_pair(1, 3), std::make_pair(2, 7)));
+/// }
+///
+
+#include <boost/hof/pack.hpp>
+#include <boost/hof/always.hpp>
+#include <boost/hof/detail/callable_base.hpp>
+#include <boost/hof/detail/make.hpp>
+
+namespace boost { namespace hof { namespace detail {
+
+template<class S, class F, class... Gs>
+struct combine_adaptor_base;
+
+template<std::size_t... Ns, class F, class... Gs>
+struct combine_adaptor_base<seq<Ns...>, F, Gs...>
+: F, pack_base<seq<Ns...>, Gs...>
+{
+ typedef pack_base<seq<Ns...>, Gs...> base_type;
+
+ BOOST_HOF_INHERIT_DEFAULT(combine_adaptor_base, base_type, F)
+
+ template<class X, class... Xs,
+ BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(F, X),
+ BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(base_type, Xs...)>
+ constexpr combine_adaptor_base(X&& x, Xs&&... xs)
+ : F(BOOST_HOF_FORWARD(X)(x)), base_type(BOOST_HOF_FORWARD(Xs)(xs)...)
+ {}
+
+ template<class... Ts>
+ constexpr const F& base_function(Ts&&... xs) const
+ {
+ return boost::hof::always_ref(*this)(xs...);
+ }
+
+ BOOST_HOF_RETURNS_CLASS(combine_adaptor_base);
+
+// Result needs to be calculated in a separate class to avoid confusing the
+// compiler on MSVC
+#if BOOST_HOF_NO_EXPRESSION_SFINAE || BOOST_HOF_HAS_MANUAL_DEDUCTION
+ template<class... Ts>
+ struct combine_result
+ : result_of<const F&, result_of<const Gs&, id_<Ts>>...>
+ {};
+#endif
+
+ template<class... Ts>
+#if BOOST_HOF_NO_EXPRESSION_SFINAE || BOOST_HOF_HAS_MANUAL_DEDUCTION
+ constexpr typename combine_result<Ts...>::type
+#else
+ constexpr auto
+#endif
+ operator()(Ts&&... xs) const BOOST_HOF_SFINAE_MANUAL_RETURNS
+ (
+ (BOOST_HOF_MANGLE_CAST(const F&)(BOOST_HOF_CONST_THIS->base_function(xs...)))
+ (boost::hof::alias_value<pack_tag<seq<Ns>, Gs...>, Gs>(*BOOST_HOF_CONST_THIS, xs)(BOOST_HOF_FORWARD(Ts)(xs))...)
+ );
+};
+
+}
+
+template<class F, class... Gs>
+struct combine_adaptor
+: detail::combine_adaptor_base<typename detail::gens<sizeof...(Gs)>::type, detail::callable_base<F>, detail::callable_base<Gs>...>
+{
+ typedef detail::combine_adaptor_base<typename detail::gens<sizeof...(Gs)>::type, detail::callable_base<F>, detail::callable_base<Gs>...> base_type;
+ BOOST_HOF_INHERIT_CONSTRUCTOR(combine_adaptor, base_type)
+};
+
+BOOST_HOF_DECLARE_STATIC_VAR(combine, detail::make<combine_adaptor>);
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/compose.hpp b/boost/hof/compose.hpp
new file mode 100644
index 0000000000..ec6b611611
--- /dev/null
+++ b/boost/hof/compose.hpp
@@ -0,0 +1,169 @@
+/*=============================================================================
+ Copyright (c) 2014 Paul Fultz II
+ compose.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FUNCTION_COMPOSE_H
+#define BOOST_HOF_GUARD_FUNCTION_COMPOSE_H
+
+/// compose
+/// =======
+///
+/// Description
+/// -----------
+///
+/// The `compose` function adaptor provides function composition. It produces
+/// a function object that composes a set of functions, ie the output of one
+/// function becomes the input of the second function. So, `compose(f, g)(0)`
+/// is equivalent to `f(g(0))`.
+///
+///
+/// Synopsis
+/// --------
+///
+/// template<class... Fs>
+/// constexpr compose_adaptor<Fs...> compose(Fs... fs);
+///
+/// Semantics
+/// ---------
+///
+/// assert(compose(f, g)(xs...) == f(g(xs...)));
+///
+/// Requirements
+/// ------------
+///
+/// Fs must be:
+///
+/// * [ConstInvocable](ConstInvocable)
+/// * MoveConstructible
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+/// using namespace boost::hof;
+///
+/// struct increment
+/// {
+/// template<class T>
+/// T operator()(T x) const
+/// {
+/// return x + 1;
+/// }
+/// };
+///
+/// struct decrement
+/// {
+/// template<class T>
+/// T operator()(T x) const
+/// {
+/// return x - 1;
+/// }
+/// };
+///
+/// int main() {
+/// int r = compose(increment(), decrement(), increment())(3);
+/// assert(r == 4);
+/// }
+///
+/// References
+/// ----------
+///
+/// * [Function composition](https://en.wikipedia.org/wiki/Function_composition)
+///
+///
+
+#include <boost/hof/detail/callable_base.hpp>
+#include <boost/hof/always.hpp>
+#include <boost/hof/detail/delegate.hpp>
+#include <boost/hof/detail/compressed_pair.hpp>
+#include <boost/hof/detail/join.hpp>
+#include <tuple>
+#include <boost/hof/detail/move.hpp>
+#include <boost/hof/detail/make.hpp>
+#include <boost/hof/detail/result_type.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+
+namespace boost { namespace hof { namespace detail {
+
+template<class F1, class F2>
+struct compose_kernel : detail::compressed_pair<F1, F2>, compose_function_result_type<F1, F2>
+{
+ typedef detail::compressed_pair<F1, F2> base_type;
+
+ BOOST_HOF_INHERIT_CONSTRUCTOR(compose_kernel, base_type)
+
+ BOOST_HOF_RETURNS_CLASS(compose_kernel);
+
+ template<class... Ts>
+ constexpr BOOST_HOF_SFINAE_RESULT(const F1&, result_of<const F2&, id_<Ts>...>)
+ operator()(Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS
+ (
+ BOOST_HOF_MANGLE_CAST(const F1&)(BOOST_HOF_CONST_THIS->first(xs...))(
+ BOOST_HOF_MANGLE_CAST(const F2&)(BOOST_HOF_CONST_THIS->second(xs...))(BOOST_HOF_FORWARD(Ts)(xs)...)
+ )
+ );
+};
+}
+
+template<class F, class... Fs>
+struct compose_adaptor
+: detail::compose_kernel<detail::callable_base<F>, BOOST_HOF_JOIN(compose_adaptor, detail::callable_base<Fs>...)>
+{
+ typedef compose_adaptor fit_rewritable_tag;
+ typedef BOOST_HOF_JOIN(compose_adaptor, detail::callable_base<Fs>...) tail;
+ typedef detail::compose_kernel<detail::callable_base<F>, tail> base_type;
+
+ BOOST_HOF_INHERIT_DEFAULT(compose_adaptor, base_type)
+
+ template<class X, class... Xs,
+ BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(detail::callable_base<F>, X),
+ BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(tail, Xs...)
+ >
+ constexpr compose_adaptor(X&& f1, Xs&& ... fs)
+ BOOST_HOF_NOEXCEPT(BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(base_type, X&&, tail) && BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(tail, Xs&&...))
+ : base_type(BOOST_HOF_FORWARD(X)(f1), tail(BOOST_HOF_FORWARD(Xs)(fs)...))
+ {}
+
+ template<class X,
+ BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(detail::callable_base<F>, X)
+ >
+ constexpr compose_adaptor(X&& f1)
+ BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(base_type, X&&)
+ : base_type(BOOST_HOF_FORWARD(X)(f1))
+ {}
+};
+
+template<class F>
+struct compose_adaptor<F> : detail::callable_base<F>
+{
+ typedef compose_adaptor fit_rewritable_tag;
+
+ BOOST_HOF_INHERIT_DEFAULT(compose_adaptor, detail::callable_base<F>)
+
+ template<class X, BOOST_HOF_ENABLE_IF_CONVERTIBLE(X, detail::callable_base<F>)>
+ constexpr compose_adaptor(X&& f1)
+ BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(detail::callable_base<F>, X&&)
+ : detail::callable_base<F>(BOOST_HOF_FORWARD(X)(f1))
+ {}
+
+};
+
+template<class F1, class F2>
+struct compose_adaptor<F1, F2>
+: detail::compose_kernel<detail::callable_base<F1>, detail::callable_base<F2>>
+{
+ typedef compose_adaptor fit_rewritable_tag;
+ typedef detail::compose_kernel<detail::callable_base<F1>, detail::callable_base<F2>> base_type;
+
+ BOOST_HOF_INHERIT_CONSTRUCTOR(compose_adaptor, base_type)
+};
+
+BOOST_HOF_DECLARE_STATIC_VAR(compose, detail::make<compose_adaptor>);
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/config.hpp b/boost/hof/config.hpp
new file mode 100644
index 0000000000..77e80e399a
--- /dev/null
+++ b/boost/hof/config.hpp
@@ -0,0 +1,201 @@
+/*=============================================================================
+ Copyright (c) 2016 Paul Fultz II
+ config.hpp
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_CONFIG_HPP
+#define BOOST_HOF_GUARD_CONFIG_HPP
+
+// Unpack has extra checks to ensure that the function will be invoked with
+// the sequence. This extra check can help improve error reporting but it can
+// slow down compilation. This is enabled by default.
+#ifndef BOOST_HOF_CHECK_UNPACK_SEQUENCE
+#define BOOST_HOF_CHECK_UNPACK_SEQUENCE 1
+#endif
+
+// Check for std version
+#if __cplusplus >= 201606
+#define BOOST_HOF_HAS_STD_17 1
+#else
+#define BOOST_HOF_HAS_STD_17 0
+#endif
+
+#if __cplusplus >= 201402
+#define BOOST_HOF_HAS_STD_14 1
+#else
+#define BOOST_HOF_HAS_STD_14 0
+#endif
+
+#if __cplusplus >= 201103
+#define BOOST_HOF_HAS_STD_11 1
+#else
+#define BOOST_HOF_HAS_STD_11 0
+#endif
+
+
+// This determines if it safe to use inheritance for EBO. On every platform
+// except clang, compilers have problems with ambigous base conversion. So
+// this configures the library to use a different technique to achieve empty
+// optimization.
+#ifndef BOOST_HOF_HAS_EBO
+#ifdef __clang__
+#define BOOST_HOF_HAS_EBO 1
+#else
+#define BOOST_HOF_HAS_EBO 0
+#endif
+#endif
+
+// This configures the library whether expression sfinae can be used to detect
+// callability of a function.
+#ifndef BOOST_HOF_NO_EXPRESSION_SFINAE
+#ifdef _MSC_VER
+#define BOOST_HOF_NO_EXPRESSION_SFINAE 1
+#else
+#define BOOST_HOF_NO_EXPRESSION_SFINAE 0
+#endif
+#endif
+
+// This configures the library to use manual type deduction in a few places
+// where it problematic on a few platforms.
+#ifndef BOOST_HOF_HAS_MANUAL_DEDUCTION
+#if (defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 8)
+#define BOOST_HOF_HAS_MANUAL_DEDUCTION 1
+#else
+#define BOOST_HOF_HAS_MANUAL_DEDUCTION 0
+#endif
+#endif
+
+// Whether the compiler has relaxed constexpr.
+#ifndef BOOST_HOF_HAS_RELAXED_CONSTEXPR
+#ifdef __cpp_constexpr
+#if __cpp_constexpr >= 201304
+#define BOOST_HOF_HAS_RELAXED_CONSTEXPR 1
+#else
+#define BOOST_HOF_HAS_RELAXED_CONSTEXPR 0
+#endif
+#else
+#define BOOST_HOF_HAS_RELAXED_CONSTEXPR BOOST_HOF_HAS_STD_14
+#endif
+#endif
+
+// Whether the compiler supports generic lambdas
+#ifndef BOOST_HOF_HAS_GENERIC_LAMBDA
+#if defined(__cpp_generic_lambdas) || defined(_MSC_VER)
+#define BOOST_HOF_HAS_GENERIC_LAMBDA 1
+#else
+#define BOOST_HOF_HAS_GENERIC_LAMBDA BOOST_HOF_HAS_STD_14
+#endif
+#endif
+
+// Whether the compiler supports constexpr lambdas
+#ifndef BOOST_HOF_HAS_CONSTEXPR_LAMBDA
+#if defined(__cpp_constexpr) && __cpp_constexpr >= 201603
+#define BOOST_HOF_HAS_CONSTEXPR_LAMBDA 1
+#else
+#define BOOST_HOF_HAS_CONSTEXPR_LAMBDA BOOST_HOF_HAS_STD_17
+#endif
+#endif
+
+// Whether the compiler supports inline variables
+#ifndef BOOST_HOF_HAS_INLINE_VARIABLES
+#if defined(__cpp_inline_variables)
+#define BOOST_HOF_HAS_INLINE_VARIABLES 1
+#else
+#define BOOST_HOF_HAS_INLINE_VARIABLES BOOST_HOF_HAS_STD_17
+#endif
+#endif
+
+// Whether inline variables defined with lambdas have external linkage.
+// Currently, no compiler supports this yet.
+#ifndef BOOST_HOF_HAS_INLINE_LAMBDAS
+#define BOOST_HOF_HAS_INLINE_LAMBDAS 0
+#endif
+
+// Whether the compiler supports variable templates
+#ifndef BOOST_HOF_HAS_VARIABLE_TEMPLATES
+#if defined(__clang__) && __clang_major__ == 3 && __clang_minor__ < 5
+#define BOOST_HOF_HAS_VARIABLE_TEMPLATES 0
+#elif defined(__cpp_variable_templates)
+#define BOOST_HOF_HAS_VARIABLE_TEMPLATES 1
+#else
+#define BOOST_HOF_HAS_VARIABLE_TEMPLATES BOOST_HOF_HAS_STD_14
+#endif
+#endif
+
+// Whether a constexpr function can use a void return type
+#ifndef BOOST_HOF_NO_CONSTEXPR_VOID
+#if BOOST_HOF_HAS_RELAXED_CONSTEXPR
+#define BOOST_HOF_NO_CONSTEXPR_VOID 0
+#else
+#define BOOST_HOF_NO_CONSTEXPR_VOID 1
+#endif
+#endif
+
+// Whether to use template aliases
+#ifndef BOOST_HOF_HAS_TEMPLATE_ALIAS
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 8
+#define BOOST_HOF_HAS_TEMPLATE_ALIAS 0
+#else
+#define BOOST_HOF_HAS_TEMPLATE_ALIAS 1
+#endif
+#endif
+
+// Whether evaluations of function in brace initialization is ordered from
+// left-to-right.
+#ifndef BOOST_HOF_NO_ORDERED_BRACE_INIT
+#if (defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 9) || defined(_MSC_VER)
+#define BOOST_HOF_NO_ORDERED_BRACE_INIT 1
+#else
+#define BOOST_HOF_NO_ORDERED_BRACE_INIT 0
+#endif
+#endif
+
+// Whether the compiler has trouble mangling some expressions used in
+// decltype.
+#ifndef BOOST_HOF_HAS_MANGLE_OVERLOAD
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7
+#define BOOST_HOF_HAS_MANGLE_OVERLOAD 0
+#else
+#define BOOST_HOF_HAS_MANGLE_OVERLOAD 1
+#endif
+#endif
+
+// Whether an incomplete 'this' pointer can be used in a trailing decltype.
+#ifndef BOOST_HOF_HAS_COMPLETE_DECLTYPE
+#if !BOOST_HOF_HAS_MANGLE_OVERLOAD || (defined(__GNUC__) && !defined (__clang__))
+#define BOOST_HOF_HAS_COMPLETE_DECLTYPE 0
+#else
+#define BOOST_HOF_HAS_COMPLETE_DECLTYPE 1
+#endif
+#endif
+
+// Whether function will deduce noexcept from an expression
+#ifndef BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
+#if defined(__GNUC__) && !defined (__clang__) && ((__GNUC__ == 4 && __GNUC_MINOR__ < 8) || (__GNUC__ == 7 && __GNUC_MINOR__ == 1))
+#define BOOST_HOF_HAS_NOEXCEPT_DEDUCTION 0
+#else
+#define BOOST_HOF_HAS_NOEXCEPT_DEDUCTION 1
+#endif
+#endif
+
+// Some type expansion failures on gcc 4.6
+#ifndef BOOST_HOF_NO_TYPE_PACK_EXPANSION_IN_TEMPLATE
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7
+#define BOOST_HOF_NO_TYPE_PACK_EXPANSION_IN_TEMPLATE 1
+#else
+#define BOOST_HOF_NO_TYPE_PACK_EXPANSION_IN_TEMPLATE 0
+#endif
+#endif
+
+// Whether to use std::default_constructible, it is a little buggy on gcc 4.6.
+#ifndef BOOST_HOF_NO_STD_DEFAULT_CONSTRUCTIBLE
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7
+#define BOOST_HOF_NO_STD_DEFAULT_CONSTRUCTIBLE 1
+#else
+#define BOOST_HOF_NO_STD_DEFAULT_CONSTRUCTIBLE 0
+#endif
+#endif
+
+#endif
diff --git a/boost/hof/construct.hpp b/boost/hof/construct.hpp
new file mode 100644
index 0000000000..daf9eca42f
--- /dev/null
+++ b/boost/hof/construct.hpp
@@ -0,0 +1,302 @@
+/*=============================================================================
+ Copyright (c) 2015 Paul Fultz II
+ construct.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_CONSTRUCT_H
+#define BOOST_HOF_GUARD_CONSTRUCT_H
+
+/// construct
+/// =========
+///
+/// Description
+/// -----------
+///
+/// The `construct` function returns a function object that will construct the
+/// object when the called. A template can also be given, which it will deduce
+/// the parameters to the template. The `construct_meta` can be used to
+/// construct the object from a metafunction.
+///
+/// Synopsis
+/// --------
+///
+/// // Construct by decaying each value
+/// template<class T>
+/// constexpr auto construct();
+///
+/// template<template<class...> class Template>
+/// constexpr auto construct();
+///
+/// // Construct by deducing lvalues by reference and rvalue reference by reference
+/// template<class T>
+/// constexpr auto construct_forward();
+///
+/// template<template<class...> class Template>
+/// constexpr auto construct_forward();
+///
+/// // Construct by deducing lvalues by reference and rvalues by value.
+/// template<class T>
+/// constexpr auto construct_basic();
+///
+/// template<template<class...> class Template>
+/// constexpr auto construct_basic();
+///
+/// // Construct by deducing the object from a metafunction
+/// template<class MetafunctionClass>
+/// constexpr auto construct_meta();
+///
+/// template<template<class...> class MetafunctionTemplate>
+/// constexpr auto construct_meta();
+///
+/// Semantics
+/// ---------
+///
+/// assert(construct<T>()(xs...) == T(xs...));
+/// assert(construct<Template>()(xs...) == Template<decltype(xs)...>(xs...));
+/// assert(construct_meta<MetafunctionClass>()(xs...) == MetafunctionClass::apply<decltype(xs)...>(xs...));
+/// assert(construct_meta<MetafunctionTemplate>()(xs...) == MetafunctionTemplate<decltype(xs)...>::type(xs...));
+///
+/// Requirements
+/// ------------
+///
+/// MetafunctionClass must be a:
+///
+/// * [MetafunctionClass](MetafunctionClass)
+///
+/// MetafunctionTemplate<Ts...> must be a:
+///
+/// * [Metafunction](Metafunction)
+///
+/// T, Template<Ts..>, MetafunctionClass::apply<Ts...>, and
+/// MetafunctionTemplate<Ts...>::type must be:
+///
+/// * MoveConstructible
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+/// #include <vector>
+///
+/// int main() {
+/// auto v = boost::hof::construct<std::vector<int>>()(5, 5);
+/// assert(v.size() == 5);
+/// }
+///
+
+#include <boost/hof/detail/forward.hpp>
+#include <boost/hof/detail/move.hpp>
+#include <boost/hof/detail/delegate.hpp>
+#include <boost/hof/detail/join.hpp>
+#include <boost/hof/detail/remove_rvalue_reference.hpp>
+#include <boost/hof/decay.hpp>
+
+#include <initializer_list>
+
+namespace boost { namespace hof {
+
+namespace detail {
+
+template<class T, class=void>
+struct construct_f
+{
+ typedef typename std::aligned_storage<sizeof(T)>::type storage;
+
+ struct storage_holder
+ {
+ storage * s;
+ storage_holder(storage* x) noexcept : s(x)
+ {}
+
+ T& data() noexcept
+ {
+ return *reinterpret_cast<T*>(s);
+ }
+
+ ~storage_holder() noexcept(noexcept(std::declval<T>().~T()))
+ {
+ this->data().~T();
+ }
+ };
+
+ constexpr construct_f() noexcept
+ {}
+ template<class... Ts, BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(T, Ts...)>
+ T operator()(Ts&&... xs) const BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(T, Ts&&...)
+ {
+ storage buffer{};
+ new(&buffer) T(BOOST_HOF_FORWARD(Ts)(xs)...);
+ storage_holder h(&buffer);
+ return boost::hof::move(h.data());
+ }
+
+ template<class X, BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(T, std::initializer_list<X>&&)>
+ T operator()(std::initializer_list<X>&& x) const BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(T, std::initializer_list<X>&&)
+ {
+ storage buffer{};
+ new(&buffer) T(static_cast<std::initializer_list<X>&&>(x));
+ storage_holder h(&buffer);
+ return h.data();
+ }
+
+ template<class X, BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(T, std::initializer_list<X>&)>
+ T operator()(std::initializer_list<X>& x) const BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(T, std::initializer_list<X>&)
+ {
+ storage buffer{};
+ new(&buffer) T(x);
+ storage_holder h(&buffer);
+ return h.data();
+ }
+
+ template<class X, BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(T, const std::initializer_list<X>&)>
+ T operator()(const std::initializer_list<X>& x) const BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(T, const std::initializer_list<X>&)
+ {
+ storage buffer{};
+ new(&buffer) T(x);
+ storage_holder h(&buffer);
+ return h.data();
+ }
+};
+
+template<class T>
+struct construct_f<T, typename std::enable_if<BOOST_HOF_IS_LITERAL(T)>::type>
+{
+ constexpr construct_f() noexcept
+ {}
+ template<class... Ts, BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(T, Ts...)>
+ constexpr T operator()(Ts&&... xs) const noexcept
+ {
+ return T(BOOST_HOF_FORWARD(Ts)(xs)...);
+ }
+
+ template<class X, BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(T, std::initializer_list<X>&&)>
+ constexpr T operator()(std::initializer_list<X>&& x) const noexcept
+ {
+ return T(static_cast<std::initializer_list<X>&&>(x));
+ }
+
+ template<class X, BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(T, std::initializer_list<X>&)>
+ constexpr T operator()(std::initializer_list<X>& x) const noexcept
+ {
+ return T(x);
+ }
+
+ template<class X, BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(T, const std::initializer_list<X>&)>
+ constexpr T operator()(const std::initializer_list<X>& x) const noexcept
+ {
+ return T(x);
+ }
+};
+
+template<template<class...> class Template, template<class...> class D>
+struct construct_template_f
+{
+ constexpr construct_template_f() noexcept
+ {}
+ template<class... Ts, class Result=BOOST_HOF_JOIN(Template, typename D<Ts>::type...),
+ BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(Result, Ts...)>
+ constexpr Result operator()(Ts&&... xs) const BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(Result, Ts&&...)
+ {
+ return construct_f<Result>()(BOOST_HOF_FORWARD(Ts)(xs)...);
+ }
+};
+
+template<class MetafunctionClass>
+struct construct_meta_f
+{
+ constexpr construct_meta_f() noexcept
+ {}
+
+ template<class... Ts>
+ struct apply
+ : MetafunctionClass::template apply<Ts...>
+ {};
+
+ template<class... Ts,
+ class Metafunction=BOOST_HOF_JOIN(apply, Ts...),
+ class Result=typename Metafunction::type,
+ BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(Result, Ts...)>
+ constexpr Result operator()(Ts&&... xs) const BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(Result, Ts&&...)
+ {
+ return construct_f<Result>()(BOOST_HOF_FORWARD(Ts)(xs)...);
+ }
+};
+
+template<template<class...> class MetafunctionTemplate>
+struct construct_meta_template_f
+{
+ constexpr construct_meta_template_f() noexcept
+ {}
+ template<class... Ts,
+ class Metafunction=BOOST_HOF_JOIN(MetafunctionTemplate, Ts...),
+ class Result=typename Metafunction::type,
+ BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(Result, Ts...)>
+ constexpr Result operator()(Ts&&... xs) const BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(Result, Ts&&...)
+ {
+ return construct_f<Result>()(BOOST_HOF_FORWARD(Ts)(xs)...);
+ }
+};
+
+
+template<class T>
+struct construct_id
+{
+ typedef T type;
+};
+
+}
+
+template<class T>
+constexpr detail::construct_f<T> construct() noexcept
+{
+ return {};
+}
+// These overloads are provide for consistency
+template<class T>
+constexpr detail::construct_f<T> construct_forward() noexcept
+{
+ return {};
+}
+
+template<class T>
+constexpr detail::construct_f<T> construct_basic() noexcept
+{
+ return {};
+}
+
+template<template<class...> class Template>
+constexpr detail::construct_template_f<Template, detail::decay_mf> construct() noexcept
+{
+ return {};
+}
+
+template<template<class...> class Template>
+constexpr detail::construct_template_f<Template, detail::construct_id> construct_forward() noexcept
+{
+ return {};
+}
+
+template<template<class...> class Template>
+constexpr detail::construct_template_f<Template, detail::remove_rvalue_reference> construct_basic() noexcept
+{
+ return {};
+}
+
+template<class T>
+constexpr detail::construct_meta_f<T> construct_meta() noexcept
+{
+ return {};
+}
+
+template<template<class...> class Template>
+constexpr detail::construct_meta_template_f<Template> construct_meta() noexcept
+{
+ return {};
+}
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/decay.hpp b/boost/hof/decay.hpp
new file mode 100644
index 0000000000..5b67122b67
--- /dev/null
+++ b/boost/hof/decay.hpp
@@ -0,0 +1,68 @@
+/*=============================================================================
+ Copyright (c) 2015 Paul Fultz II
+ decay.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_DECAY_H
+#define BOOST_HOF_GUARD_DECAY_H
+
+/// decay
+/// =====
+///
+/// Description
+/// -----------
+///
+/// The `decay` function is a unary function object that returns whats given to it after decaying its type.
+///
+/// Synopsis
+/// --------
+///
+/// struct
+/// {
+/// template<class T>
+/// constexpr typename decay<T>::type operator()(T&& x) const
+/// {
+/// return boost::hof::forward<T>(x);
+/// }
+/// } decay;
+///
+/// References
+/// ----------
+///
+/// * [n3255](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3255.html) - Proposal for `decay_copy`
+///
+
+#include <boost/hof/detail/delegate.hpp>
+#include <boost/hof/detail/unwrap.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+#include <boost/hof/detail/forward.hpp>
+
+namespace boost { namespace hof { namespace detail {
+
+template<class T>
+struct decay_mf
+: unwrap_reference<typename std::decay<T>::type>
+{};
+
+struct decay_f
+{
+ template<
+ class T,
+ class Result=typename unwrap_reference<typename std::decay<T>::type>::type,
+ class=typename std::enable_if<(BOOST_HOF_IS_CONSTRUCTIBLE(Result, T))>::type
+ >
+ constexpr Result operator()(T&& x) const BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(Result, T&&)
+ {
+ return BOOST_HOF_FORWARD(T)(x);
+ }
+};
+
+}
+
+BOOST_HOF_DECLARE_STATIC_VAR(decay, detail::decay_f);
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/decorate.hpp b/boost/hof/decorate.hpp
new file mode 100644
index 0000000000..9337b30488
--- /dev/null
+++ b/boost/hof/decorate.hpp
@@ -0,0 +1,217 @@
+/*=============================================================================
+ Copyright (c) 2015 Paul Fultz II
+ decorate.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_DECORATE_H
+#define BOOST_HOF_GUARD_DECORATE_H
+
+/// decorate
+/// ========
+///
+/// Description
+/// -----------
+///
+/// The `decorate` function adaptor helps create simple function decorators.
+///
+/// A function adaptor takes a function and returns a new functions whereas a
+/// decorator takes some parameters and returns a function adaptor. The
+/// `decorate` function adaptor will return a decorator that returns a
+/// function adaptor. Eventually, it will invoke the function with the user-
+/// provided parameter and function.
+///
+/// Synopsis
+/// --------
+///
+/// template<class F>
+/// constexpr decorate_adaptor<F> decorate(F f);
+///
+/// Semantics
+/// ---------
+///
+/// assert(decorate(f)(x)(g)(xs...) == f(x, g, xs...));
+///
+/// Requirements
+/// ------------
+///
+/// F must be:
+///
+/// * [ConstInvocable](ConstInvocable)
+/// * MoveConstructible
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+/// #include <iostream>
+/// #include <string>
+/// using namespace boost::hof;
+///
+/// struct logger_f
+/// {
+/// template<class F, class... Ts>
+/// auto operator()(const std::string& message, F&& f, Ts&&... xs) const
+/// -> decltype(f(std::forward<Ts>(xs)...))
+/// {
+/// // Message to print out when the function is called
+/// std::cout << message << std::endl;
+/// // Call the function
+/// return f(std::forward<Ts>(xs)...);
+/// }
+/// };
+/// // The logger decorator
+/// BOOST_HOF_STATIC_FUNCTION(logger) = boost::hof::decorate(logger_f());
+///
+/// struct sum_f
+/// {
+/// template<class T, class U>
+/// T operator()(T x, U y) const
+/// {
+/// return x+y;
+/// }
+/// };
+///
+/// BOOST_HOF_STATIC_FUNCTION(sum) = sum_f();
+/// int main() {
+/// // Use the logger decorator to print "Calling sum" when the function is called
+/// assert(3 == logger("Calling sum")(sum)(1, 2));
+/// }
+///
+
+#include <boost/hof/reveal.hpp>
+#include <boost/hof/detail/delegate.hpp>
+#include <boost/hof/detail/move.hpp>
+#include <boost/hof/detail/make.hpp>
+#include <boost/hof/detail/callable_base.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+#include <boost/hof/detail/compressed_pair.hpp>
+
+namespace boost { namespace hof { namespace detail {
+
+template<class D, class T, class F>
+struct decorator_invoke
+// : compressed_pair<compressed_pair<F, T>, D>
+: compressed_pair<compressed_pair<D, T>, F>
+{
+ // typedef compressed_pair<F, T> base;
+ typedef compressed_pair<compressed_pair<D, T>, F> base;
+
+ BOOST_HOF_INHERIT_CONSTRUCTOR(decorator_invoke, base)
+
+ template<class... Ts>
+ constexpr const compressed_pair<D, T>& get_pair(Ts&&... xs) const noexcept
+ {
+ return this->first(xs...);
+ }
+
+ template<class... Ts>
+ constexpr const F& base_function(Ts&&... xs) const noexcept
+ {
+ return this->second(xs...);
+ }
+
+ template<class... Ts>
+ constexpr const D& get_decorator(Ts&&... xs) const noexcept
+ {
+ return this->get_pair(xs...).first(xs...);
+ }
+
+ template<class... Ts>
+ constexpr const T& get_data(Ts&&... xs) const noexcept
+ {
+ return this->get_pair(xs...).second(xs...);
+ }
+
+ BOOST_HOF_RETURNS_CLASS(decorator_invoke);
+
+ struct decorator_invoke_failure
+ {
+ template<class Failure>
+ struct apply
+ {
+ template<class... Ts>
+ struct of
+ : Failure::template of<const T&, const F&, Ts...>
+ {};
+ };
+ };
+
+ struct failure
+ : failure_map<decorator_invoke_failure, D>
+ {};
+
+ template<class... Ts>
+ constexpr BOOST_HOF_SFINAE_RESULT(const D&, id_<const T&>, id_<const F&>, id_<Ts>...)
+ operator()(Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS
+ (
+ BOOST_HOF_MANGLE_CAST(const D&)(BOOST_HOF_CONST_THIS->get_decorator(xs...))(
+ BOOST_HOF_MANGLE_CAST(const T&)(BOOST_HOF_CONST_THIS->get_data(xs...)),
+ BOOST_HOF_MANGLE_CAST(const F&)(BOOST_HOF_CONST_THIS->base_function(xs...)),
+ BOOST_HOF_FORWARD(Ts)(xs)...
+ )
+ );
+};
+
+template<class D, class T>
+struct decoration
+: compressed_pair<D, T>
+{
+ typedef compressed_pair<D, T> base;
+ BOOST_HOF_INHERIT_CONSTRUCTOR(decoration, base)
+
+ template<class... Ts>
+ constexpr const D& get_decorator(Ts&&... xs) const noexcept
+ {
+ return this->first(xs...);
+ }
+
+ template<class... Ts>
+ constexpr const T& get_data(Ts&&... xs) const noexcept
+ {
+ return this->second(xs...);
+ }
+
+ template<class F>
+ constexpr decorator_invoke<D, T, detail::callable_base<F>> operator()(F f) const
+ BOOST_HOF_NOEXCEPT(BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(decorator_invoke<D, T, detail::callable_base<F>>, compressed_pair<D, T>, detail::callable_base<F>&&))
+ {
+ return decorator_invoke<D, T, detail::callable_base<F>>(
+ *this, static_cast<detail::callable_base<F>&&>(f)
+ );
+ }
+};
+
+}
+
+template<class F>
+struct decorate_adaptor : detail::callable_base<F>
+{
+ typedef decorate_adaptor fit_rewritable1_tag;
+ typedef detail::callable_base<F> base;
+ BOOST_HOF_INHERIT_CONSTRUCTOR(decorate_adaptor, detail::callable_base<F>)
+
+ template<class... Ts>
+ constexpr const base& base_function(Ts&&... xs) const noexcept
+ {
+ return boost::hof::always_ref(*this)(xs...);
+ }
+
+ // TODO: Add predicate for constraints
+
+ template<class T>
+ constexpr detail::decoration<base, T> operator()(T x) const
+ BOOST_HOF_NOEXCEPT(BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(base, const base&) && BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(T, T&&))
+ {
+ return detail::decoration<base, T>(this->base_function(x), static_cast<T&&>(x));
+ }
+
+};
+
+BOOST_HOF_DECLARE_STATIC_VAR(decorate, detail::make<decorate_adaptor>);
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/detail/and.hpp b/boost/hof/detail/and.hpp
new file mode 100644
index 0000000000..8a7e50a36e
--- /dev/null
+++ b/boost/hof/detail/and.hpp
@@ -0,0 +1,55 @@
+/*=============================================================================
+ Copyright (c) 2015 Paul Fultz II
+ and.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_AND_H
+#define BOOST_HOF_GUARD_AND_H
+
+#include <type_traits>
+#include <boost/hof/detail/using.hpp>
+#include <boost/hof/detail/intrinsics.hpp>
+
+namespace boost { namespace hof { namespace detail {
+
+constexpr bool and_c()
+{
+ return true;
+}
+
+template<class... Ts>
+constexpr bool and_c(bool b, Ts... bs)
+{
+ return b && and_c(bs...);
+}
+
+#ifdef _MSC_VER
+
+template<class... Ts>
+struct and_;
+
+template<class T, class... Ts>
+struct and_<T, Ts...>
+: std::integral_constant<bool, (T::value && and_<Ts...>::value)>
+{};
+
+template<>
+struct and_<>
+: std::true_type
+{};
+
+#define BOOST_HOF_AND_UNPACK(Bs) (boost::hof::detail::and_c(Bs...))
+#else
+template<bool...> struct bool_seq {};
+template<class... Ts>
+BOOST_HOF_USING(and_, std::is_same<bool_seq<Ts::value...>, bool_seq<(Ts::value, true)...>>);
+
+#define BOOST_HOF_AND_UNPACK(Bs) BOOST_HOF_IS_BASE_OF(boost::hof::detail::bool_seq<Bs...>, boost::hof::detail::bool_seq<(Bs || true)...>)
+
+#endif
+
+}}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/detail/callable_base.hpp b/boost/hof/detail/callable_base.hpp
new file mode 100644
index 0000000000..b214043e0b
--- /dev/null
+++ b/boost/hof/detail/callable_base.hpp
@@ -0,0 +1,65 @@
+/*=============================================================================
+ Copyright (c) 2015 Paul Fultz II
+ callable_base.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_CALLABLE_BASE_H
+#define BOOST_HOF_GUARD_CALLABLE_BASE_H
+
+#include <boost/hof/detail/delegate.hpp>
+#include <boost/hof/detail/result_of.hpp>
+#include <boost/hof/apply.hpp>
+
+#ifndef BOOST_HOF_CALLABLE_BASE_USE_TEMPLATE_ALIAS
+#if (defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7)
+#define BOOST_HOF_CALLABLE_BASE_USE_TEMPLATE_ALIAS 0
+#else
+#define BOOST_HOF_CALLABLE_BASE_USE_TEMPLATE_ALIAS 1
+#endif
+#endif
+
+namespace boost { namespace hof { namespace detail {
+
+template<class F>
+struct non_class_function
+{
+ F f;
+ BOOST_HOF_DELEGATE_CONSTRUCTOR(non_class_function, F, f)
+
+ template<class... Ts>
+ constexpr BOOST_HOF_SFINAE_RESULT(apply_f, id_<F>, id_<Ts>...)
+ operator()(Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS
+ (
+ boost::hof::apply(f, BOOST_HOF_FORWARD(Ts)(xs)...)
+ );
+};
+
+template<class F>
+struct callable_base_type
+: std::conditional<(BOOST_HOF_IS_CLASS(F) && !BOOST_HOF_IS_FINAL(F) && !BOOST_HOF_IS_POLYMORPHIC(F)), F, non_class_function<F>>
+{};
+
+#if BOOST_HOF_CALLABLE_BASE_USE_TEMPLATE_ALIAS
+template<class F>
+using callable_base = typename callable_base_type<F>::type;
+#else
+template<class F>
+struct callable_base
+: callable_base_type<F>::type
+{
+ typedef typename callable_base_type<F>::type base;
+ BOOST_HOF_INHERIT_CONSTRUCTOR(callable_base, base)
+};
+
+template<class F>
+struct callable_base_type<callable_base<F>>
+: callable_base_type<F>
+{};
+
+#endif
+
+}}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/detail/can_be_called.hpp b/boost/hof/detail/can_be_called.hpp
new file mode 100644
index 0000000000..7cf6751da8
--- /dev/null
+++ b/boost/hof/detail/can_be_called.hpp
@@ -0,0 +1,121 @@
+/*=============================================================================
+ Copyright (c) 2015 Paul Fultz II
+ can_be_called.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_CAN_BE_CALLED_H
+#define BOOST_HOF_GUARD_CAN_BE_CALLED_H
+
+#include <boost/hof/config.hpp>
+#include <boost/hof/detail/and.hpp>
+#include <boost/hof/detail/holder.hpp>
+#include <boost/hof/detail/using.hpp>
+
+namespace boost { namespace hof { namespace detail {
+
+#if BOOST_HOF_NO_EXPRESSION_SFINAE
+struct dont_care
+{
+ dont_care(...);
+};
+
+template<class T>
+struct never_care
+{
+ typedef dont_care type;
+};
+
+struct cant_be_called_type
+{};
+
+struct no_type
+{};
+
+template<class F>
+struct is_callable_wrapper_fallback
+{
+ template<class... Ts>
+ auto operator()(Ts&&...) const
+ -> decltype(std::declval<F>()(std::declval<Ts>()...));
+};
+
+template<class T, class U=typename std::remove_cv<typename std::remove_reference<T>::type>::type>
+struct is_callable_wrapper_base
+: std::conditional<BOOST_HOF_IS_CLASS(U) && !BOOST_HOF_IS_FINAL(U), U, is_callable_wrapper_fallback<U>>
+{};
+
+template<class F, class... Ts>
+struct is_callable_wrapper : is_callable_wrapper_base<F>::type
+{
+ is_callable_wrapper();
+ typedef cant_be_called_type const &(*pointer_to_function)(typename never_care<Ts>::type...);
+ operator pointer_to_function() const;
+};
+
+template<class T>
+struct not_
+: std::integral_constant<bool, !T::value>
+{};
+
+template<class F, class... Ts>
+struct can_be_called
+: not_<std::is_same<cant_be_called_type, typename std::decay<decltype(
+ is_callable_wrapper<F, Ts...>()(std::declval<Ts>()...)
+)>::type>>
+{};
+
+template<class F, class... Ts>
+struct check_args;
+
+template<class Res, class... Ts, class... Us>
+struct check_args<Res(Us...), Ts...>
+: and_<std::is_convertible<Ts, Us>...>
+{};
+
+template<class Res, class... Ts, class... Us>
+struct can_be_called<Res(*)(Us...), Ts...>
+: std::conditional<sizeof...(Ts) == sizeof...(Us),
+ check_args<Res(Us...), Ts...>,
+ std::false_type
+>::type
+{};
+
+template<class Res, class... Ts, class... Us>
+struct can_be_called<Res(Us...), Ts...>
+: std::conditional<sizeof...(Ts) == sizeof...(Us),
+ check_args<Res(Us...), Ts...>,
+ std::false_type
+>::type
+{};
+
+#else
+
+template<class T>
+T&& called_val() noexcept;
+
+template<class... Ts>
+struct callable_args
+{};
+
+template<class F, class Args, class=void>
+struct can_be_called_impl
+: std::false_type
+{};
+
+template<class F, class... Args>
+struct can_be_called_impl<F, callable_args<Args...>, typename detail::holder<
+ decltype( boost::hof::detail::called_val<F>()(boost::hof::detail::called_val<Args>()...) )
+>::type>
+: std::true_type
+{};
+
+template<class F, class... Ts>
+BOOST_HOF_USING(can_be_called, can_be_called_impl<F, detail::callable_args<Ts...>>);
+
+#endif
+
+}}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/detail/compressed_pair.hpp b/boost/hof/detail/compressed_pair.hpp
new file mode 100644
index 0000000000..b7c320e2da
--- /dev/null
+++ b/boost/hof/detail/compressed_pair.hpp
@@ -0,0 +1,130 @@
+/*=============================================================================
+ Copyright (c) 2015 Paul Fultz II
+ compressed_pair.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_COMPRESSED_PAIR_H
+#define BOOST_HOF_GUARD_COMPRESSED_PAIR_H
+
+#include <boost/hof/detail/delegate.hpp>
+#include <boost/hof/detail/move.hpp>
+#include <boost/hof/detail/forward.hpp>
+#include <boost/hof/config.hpp>
+#include <boost/hof/always.hpp>
+#include <boost/hof/alias.hpp>
+
+#ifndef BOOST_HOF_COMPRESSED_PAIR_USE_EBO_WORKAROUND
+#define BOOST_HOF_COMPRESSED_PAIR_USE_EBO_WORKAROUND !BOOST_HOF_HAS_EBO
+#endif
+
+namespace boost { namespace hof { namespace detail {
+
+template<class First, class Second, class=void>
+struct compressed_pair;
+
+template<int I, class T, class U>
+struct pair_tag
+{};
+
+#if BOOST_HOF_COMPRESSED_PAIR_USE_EBO_WORKAROUND
+
+template<class T, class U>
+struct is_same_template
+: std::false_type
+{};
+
+template<template<class...> class X, class... Ts, class... Us>
+struct is_same_template<X<Ts...>, X<Us...>>
+: std::true_type
+{};
+
+#if (defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7)
+
+template<class T, class U>
+struct is_related_template
+: std::false_type
+{};
+
+#else
+
+template<class T, class U>
+struct is_related_template
+: is_same_template<T, U>
+{};
+
+#endif
+
+template<class T, class U>
+struct is_related
+: std::integral_constant<bool, std::is_base_of<T, U>::value || std::is_base_of<U, T>::value || is_related_template<T, U>::value>
+{};
+
+template<int I, class T, class U>
+struct pair_holder
+: std::conditional<(
+ is_related<T, U>::value),
+ detail::alias_empty<T, pair_tag<I, T, U>>,
+ detail::alias_try_inherit<T, pair_tag<I, T, U>>
+>::type
+{};
+#else
+template<int I, class T, class U>
+struct pair_holder
+: detail::alias_try_inherit<T, pair_tag<I, T, U>>
+{};
+#endif
+
+// TODO: Empty optimizations for MSVC
+template<
+ class First,
+ class Second
+>
+struct compressed_pair<First, Second>
+: pair_holder<0, First, Second>::type, pair_holder<1, Second, First>::type
+{
+ typedef typename pair_holder<0, First, Second>::type first_base;
+ typedef typename pair_holder<1, Second, First>::type second_base;
+ template<class X, class Y,
+ BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(First, X&&),
+ BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(Second, Y&&)
+ >
+ constexpr compressed_pair(X&& x, Y&& y)
+ noexcept(BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(first_base, X&&) && BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(second_base, Y&&))
+ : first_base(BOOST_HOF_FORWARD(X)(x)), second_base(BOOST_HOF_FORWARD(Y)(y))
+ {}
+
+ BOOST_HOF_INHERIT_DEFAULT(compressed_pair, first_base, second_base)
+
+ template<class Base, class... Xs>
+ constexpr const Base& get_alias_base(Xs&&... xs) const noexcept
+ {
+ return boost::hof::always_ref(*this)(xs...);
+ }
+
+ template<class... Xs>
+ constexpr const First& first(Xs&&... xs) const noexcept
+ {
+ return boost::hof::alias_value(this->get_alias_base<first_base>(xs...), xs...);
+ }
+
+ template<class... Xs>
+ constexpr const Second& second(Xs&&... xs) const noexcept
+ {
+ return boost::hof::alias_value(this->get_alias_base<second_base>(xs...), xs...);
+ }
+
+};
+
+template<class T, class U>
+constexpr compressed_pair<T, U> make_compressed_pair(T x, U y)
+noexcept(BOOST_HOF_IS_NOTHROW_MOVE_CONSTRUCTIBLE(T) && BOOST_HOF_IS_NOTHROW_MOVE_CONSTRUCTIBLE(U))
+{
+ return {static_cast<T&&>(x), static_cast<U&&>(y)};
+}
+
+
+}}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/detail/constexpr_deduce.hpp b/boost/hof/detail/constexpr_deduce.hpp
new file mode 100644
index 0000000000..80bdd5ed8a
--- /dev/null
+++ b/boost/hof/detail/constexpr_deduce.hpp
@@ -0,0 +1,74 @@
+/*=============================================================================
+ Copyright (c) 2015 Paul Fultz II
+ constexpr_deduce.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FUNCTION_CONSTEXPR_DEDUCE_H
+#define BOOST_HOF_GUARD_FUNCTION_CONSTEXPR_DEDUCE_H
+
+#include <boost/hof/config.hpp>
+
+#define BOOST_HOF_CONST_FOLD(x) (__builtin_constant_p(x) ? (x) : (x))
+
+#ifndef BOOST_HOF_HAS_CONST_FOLD
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7
+#define BOOST_HOF_HAS_CONST_FOLD 0
+#elif defined(__clang__) || defined (__GNUC__)
+#define BOOST_HOF_HAS_CONST_FOLD 1
+#else
+#define BOOST_HOF_HAS_CONST_FOLD 0
+#endif
+#endif
+
+
+namespace boost { namespace hof {
+
+namespace detail {
+
+struct constexpr_deduce
+{
+ constexpr constexpr_deduce()
+ {}
+ template<class F>
+ constexpr operator F() const
+ {
+ return F();
+ }
+};
+
+template<class T>
+struct constexpr_deduce_unique
+{
+ constexpr constexpr_deduce_unique()
+ {}
+#if BOOST_HOF_HAS_CONST_FOLD
+ template<class F>
+ constexpr operator const F&() const
+ {
+ static_assert(BOOST_HOF_IS_EMPTY(F), "Function or lambda expression must be empty");
+ return BOOST_HOF_CONST_FOLD(reinterpret_cast<const F&>(static_const_var<T>()));
+ }
+#else
+ template<class F>
+ constexpr operator F() const
+ {
+ // static_assert(std::is_default_constructible<F>::value, "Function not default constructible");
+ return F();
+ }
+#endif
+};
+
+}}} // namespace boost::hof
+
+#define BOOST_HOF_DETAIL_CONSTEXPR_DEDUCE true ? boost::hof::detail::constexpr_deduce() :
+#define BOOST_HOF_DETAIL_CONSTEXPR_DEDUCE_UNIQUE(T) true ? boost::hof::detail::constexpr_deduce_unique<T>() :
+
+#ifdef _MSC_VER
+#define BOOST_HOF_DETAIL_MSVC_CONSTEXPR_DEDUCE BOOST_HOF_DETAIL_CONSTEXPR_DEDUCE
+#else
+#define BOOST_HOF_DETAIL_MSVC_CONSTEXPR_DEDUCE
+#endif
+
+#endif
diff --git a/boost/hof/detail/delegate.hpp b/boost/hof/detail/delegate.hpp
new file mode 100644
index 0000000000..af2179680d
--- /dev/null
+++ b/boost/hof/detail/delegate.hpp
@@ -0,0 +1,107 @@
+/*=============================================================================
+ Copyright (c) 2012 Paul Fultz II
+ delgate.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FUNCTION_DELGATE_H
+#define BOOST_HOF_GUARD_FUNCTION_DELGATE_H
+
+#include <type_traits>
+#include <utility>
+#include <boost/hof/config.hpp>
+#include <boost/hof/detail/and.hpp>
+#include <boost/hof/detail/holder.hpp>
+#include <boost/hof/detail/forward.hpp>
+#include <boost/hof/detail/using.hpp>
+#include <boost/hof/detail/intrinsics.hpp>
+#include <boost/hof/detail/noexcept.hpp>
+
+
+#define BOOST_HOF_ENABLE_IF_CONVERTIBLE(...) \
+ class=typename std::enable_if<BOOST_HOF_IS_CONVERTIBLE(__VA_ARGS__)>::type
+
+#define BOOST_HOF_ENABLE_IF_CONVERTIBLE_UNPACK(...) \
+ class=typename std::enable_if<BOOST_HOF_AND_UNPACK(BOOST_HOF_IS_CONVERTIBLE(__VA_ARGS__))>::type
+
+#define BOOST_HOF_ENABLE_IF_BASE_OF(...) \
+ class=typename std::enable_if<BOOST_HOF_IS_BASE_OF(__VA_ARGS__)>::type
+
+#define BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(...) \
+ class=typename std::enable_if<BOOST_HOF_IS_CONSTRUCTIBLE(__VA_ARGS__)>::type
+
+#define BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(...) \
+ BOOST_HOF_NOEXCEPT(BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(__VA_ARGS__))
+
+#define BOOST_HOF_INHERIT_DEFAULT(C, ...) \
+ template<bool FitPrivateEnableBool_##__LINE__=true, \
+ class=typename std::enable_if<FitPrivateEnableBool_##__LINE__ && boost::hof::detail::is_default_constructible_c<__VA_ARGS__>()>::type> \
+ constexpr C() BOOST_HOF_NOEXCEPT(boost::hof::detail::is_nothrow_default_constructible_c<__VA_ARGS__>()) {}
+
+#define BOOST_HOF_INHERIT_DEFAULT_EMPTY(C, ...) \
+ template<bool FitPrivateEnableBool_##__LINE__=true, \
+ class=typename std::enable_if<FitPrivateEnableBool_##__LINE__ && \
+ boost::hof::detail::is_default_constructible_c<__VA_ARGS__>() && BOOST_HOF_IS_EMPTY(__VA_ARGS__) \
+ >::type> \
+ constexpr C() BOOST_HOF_NOEXCEPT(boost::hof::detail::is_nothrow_default_constructible_c<__VA_ARGS__>()) {}
+
+#if BOOST_HOF_NO_TYPE_PACK_EXPANSION_IN_TEMPLATE
+
+#define BOOST_HOF_DELGATE_PRIMITIVE_CONSTRUCTOR(constexpr_, C, T, var) \
+ template<class... FitXs, typename boost::hof::detail::enable_if_constructible<C, T, FitXs...>::type = 0> \
+ constexpr_ C(FitXs&&... fit_xs) \
+ BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(T, FitXs&&...) \
+ : var((FitXs&&)boost::hof::forward<FitXs>(fit_xs)...) {}
+
+#else
+#define BOOST_HOF_DELGATE_PRIMITIVE_CONSTRUCTOR(constexpr_, C, T, var) \
+ template<class... FitXs, BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(T, FitXs&&...)> \
+ constexpr_ C(FitXs&&... fit_xs) \
+ BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(T, FitXs&&...) \
+ : var(BOOST_HOF_FORWARD(FitXs)(fit_xs)...) {}
+
+#endif
+
+#define BOOST_HOF_DELEGATE_CONSTRUCTOR(C, T, var) BOOST_HOF_DELGATE_PRIMITIVE_CONSTRUCTOR(constexpr, C, T, var)
+
+// Currently its faster to use `BOOST_HOF_DELEGATE_CONSTRUCTOR` than `using
+// Base::Base;`
+#if 1
+#define BOOST_HOF_INHERIT_CONSTRUCTOR(Derived, Base) BOOST_HOF_DELEGATE_CONSTRUCTOR(Derived, Base, Base)
+#else
+#define BOOST_HOF_INHERIT_CONSTRUCTOR(Derived, Base) \
+ using fit_inherit_base = Base; \
+ using fit_inherit_base::fit_inherit_base; \
+ Derived()=default; \
+ template<class FitX, BOOST_HOF_ENABLE_IF_CONVERTIBLE(FitX, Base)> \
+ constexpr Derived(FitX&& fit_x) : Base(BOOST_HOF_FORWARD(FitX)(fit_x)) {}
+#endif
+
+namespace boost { namespace hof {
+namespace detail {
+
+template<class... Xs>
+constexpr bool is_nothrow_default_constructible_c()
+{
+ return BOOST_HOF_AND_UNPACK(BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(Xs));
+}
+
+template<class... Xs>
+constexpr bool is_default_constructible_c()
+{
+ return BOOST_HOF_AND_UNPACK(BOOST_HOF_IS_DEFAULT_CONSTRUCTIBLE(Xs));
+}
+
+template<class... Xs>
+BOOST_HOF_USING(is_default_constructible, std::integral_constant<bool, is_default_constructible_c<Xs...>()>);
+
+template<class C, class X, class... Xs>
+struct enable_if_constructible
+: std::enable_if<is_constructible<X, Xs&&...>::value, int>
+{};
+
+}
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/detail/forward.hpp b/boost/hof/detail/forward.hpp
new file mode 100644
index 0000000000..729436c4aa
--- /dev/null
+++ b/boost/hof/detail/forward.hpp
@@ -0,0 +1,37 @@
+/*=============================================================================
+ Copyright (c) 2014 Paul Fultz II
+ forward.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FORWARD_H
+#define BOOST_HOF_GUARD_FORWARD_H
+
+#include <utility>
+
+namespace boost { namespace hof {
+
+// contexpr-friendly forwarding
+
+template<typename T>
+constexpr T&& forward(typename std::remove_reference<T>::type& t) noexcept
+{ return static_cast<T&&>(t); }
+
+
+template<typename T>
+constexpr T&& forward(typename std::remove_reference<T>::type&& t) noexcept
+{
+ static_assert(!std::is_lvalue_reference<T>::value, "T must not be an lvalue reference type");
+ return static_cast<T&&>(t);
+}
+
+#if (defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7) || defined(_MSC_VER)
+#define BOOST_HOF_FORWARD(...) boost::hof::forward<__VA_ARGS__>
+#else
+#define BOOST_HOF_FORWARD(...) static_cast<__VA_ARGS__ &&>
+#endif
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/detail/holder.hpp b/boost/hof/detail/holder.hpp
new file mode 100644
index 0000000000..4a7aed2093
--- /dev/null
+++ b/boost/hof/detail/holder.hpp
@@ -0,0 +1,27 @@
+/*=============================================================================
+ Copyright (c) 2014 Paul Fultz II
+ holder.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_HOLDER_H
+#define BOOST_HOF_GUARD_HOLDER_H
+
+namespace boost { namespace hof { namespace detail {
+
+template<class... Ts>
+struct holder
+{
+ typedef void type;
+};
+
+template<template<class...> class T>
+struct template_holder
+{
+ typedef void type;
+};
+
+}}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/detail/intrinsics.hpp b/boost/hof/detail/intrinsics.hpp
new file mode 100644
index 0000000000..1ace7d6882
--- /dev/null
+++ b/boost/hof/detail/intrinsics.hpp
@@ -0,0 +1,113 @@
+/*=============================================================================
+ Copyright (c) 2016 Paul Fultz II
+ intrinsics.hpp
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_INTRINSICS_HPP
+#define BOOST_HOF_GUARD_INTRINSICS_HPP
+
+#include <type_traits>
+#include <boost/hof/detail/holder.hpp>
+#include <boost/hof/config.hpp>
+
+// *** clang ***
+#if defined(__clang__)
+// #define BOOST_HOF_IS_CONSTRUCTIBLE(...) std::is_constructible<__VA_ARGS__>::value
+// #define BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(...) std::is_nothrow_constructible<__VA_ARGS__>::value
+// #define BOOST_HOF_IS_CONVERTIBLE(...) std::is_convertible<__VA_ARGS__>::value
+#define BOOST_HOF_IS_CONSTRUCTIBLE(...) __is_constructible(__VA_ARGS__)
+#define BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(...) __is_nothrow_constructible(__VA_ARGS__)
+#define BOOST_HOF_IS_CONVERTIBLE(...) __is_convertible_to(__VA_ARGS__)
+#define BOOST_HOF_IS_BASE_OF(...) __is_base_of(__VA_ARGS__)
+#define BOOST_HOF_IS_CLASS(...) __is_class(__VA_ARGS__)
+#define BOOST_HOF_IS_EMPTY(...) __is_empty(__VA_ARGS__)
+#define BOOST_HOF_IS_LITERAL(...) __is_literal(__VA_ARGS__)
+#define BOOST_HOF_IS_POLYMORPHIC(...) __is_polymorphic(__VA_ARGS__)
+#define BOOST_HOF_IS_FINAL(...) __is_final(__VA_ARGS__)
+#define BOOST_HOF_IS_NOTHROW_COPY_CONSTRUCTIBLE(...) __has_nothrow_copy(__VA_ARGS__)
+// *** gcc ***
+#elif defined(__GNUC__)
+#define BOOST_HOF_IS_CONSTRUCTIBLE(...) std::is_constructible<__VA_ARGS__>::value
+#define BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(...) std::is_nothrow_constructible<__VA_ARGS__>::value
+#define BOOST_HOF_IS_CONVERTIBLE(...) std::is_convertible<__VA_ARGS__>::value
+#define BOOST_HOF_IS_BASE_OF(...) __is_base_of(__VA_ARGS__)
+#define BOOST_HOF_IS_CLASS(...) __is_class(__VA_ARGS__)
+#define BOOST_HOF_IS_EMPTY(...) __is_empty(__VA_ARGS__)
+#define BOOST_HOF_IS_LITERAL(...) __is_literal_type(__VA_ARGS__)
+#define BOOST_HOF_IS_POLYMORPHIC(...) __is_polymorphic(__VA_ARGS__)
+#define BOOST_HOF_IS_NOTHROW_COPY_CONSTRUCTIBLE(...) __has_nothrow_copy(__VA_ARGS__)
+#if __GNUC__ == 4 && __GNUC_MINOR__ < 7
+#define BOOST_HOF_IS_FINAL(...) (false)
+#else
+#define BOOST_HOF_IS_FINAL(...) __is_final(__VA_ARGS__)
+#endif
+#define BOOST_HOF_IS_NOTHROW_COPY_CONSTRUCTIBLE(...) __has_nothrow_copy(__VA_ARGS__)
+// *** other ***
+#else
+#define BOOST_HOF_IS_CONSTRUCTIBLE(...) std::is_constructible<__VA_ARGS__>::value
+#define BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(...) std::is_nothrow_constructible<__VA_ARGS__>::value
+#define BOOST_HOF_IS_CONVERTIBLE(...) std::is_convertible<__VA_ARGS__>::value
+#define BOOST_HOF_IS_BASE_OF(...) std::is_base_of<__VA_ARGS__>::value
+#define BOOST_HOF_IS_CLASS(...) std::is_class<__VA_ARGS__>::value
+#define BOOST_HOF_IS_EMPTY(...) std::is_empty<__VA_ARGS__>::value
+#define BOOST_HOF_IS_LITERAL(...) std::is_literal_type<__VA_ARGS__>::value
+#define BOOST_HOF_IS_POLYMORPHIC(...) std::is_polymorphic<__VA_ARGS__>::value
+#if defined(_MSC_VER)
+#define BOOST_HOF_IS_NOTHROW_COPY_CONSTRUCTIBLE(...) (std::is_nothrow_copy_constructible<__VA_ARGS__>::value || std::is_reference<__VA_ARGS__>::value)
+#else
+#define BOOST_HOF_IS_NOTHROW_COPY_CONSTRUCTIBLE(...) std::is_nothrow_copy_constructible<__VA_ARGS__>::value
+#endif
+#if defined(_MSC_VER)
+#define BOOST_HOF_IS_FINAL(...) __is_final(__VA_ARGS__)
+#else
+#define BOOST_HOF_IS_FINAL(...) (false)
+#endif
+#endif
+
+#if BOOST_HOF_NO_STD_DEFAULT_CONSTRUCTIBLE
+#define BOOST_HOF_IS_DEFAULT_CONSTRUCTIBLE(...) boost::hof::detail::is_default_constructible_helper<__VA_ARGS__>::value
+#else
+#define BOOST_HOF_IS_DEFAULT_CONSTRUCTIBLE BOOST_HOF_IS_CONSTRUCTIBLE
+#endif
+
+#define BOOST_HOF_IS_NOTHROW_MOVE_CONSTRUCTIBLE(...) BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(__VA_ARGS__, __VA_ARGS__ &&)
+
+namespace boost { namespace hof { namespace detail {
+
+template<class T, class=void>
+struct is_default_constructible_check
+: std::false_type
+{};
+
+template<class T>
+struct is_default_constructible_check<T, typename holder<
+ decltype(T())
+>::type>
+: std::true_type
+{};
+
+template<class T>
+struct is_default_constructible_helper
+: std::conditional<(std::is_reference<T>::value),
+ std::false_type,
+ is_default_constructible_check<T>
+>::type
+{};
+
+template<class T, class... Xs>
+struct is_constructible
+: std::is_constructible<T, Xs...>
+{};
+
+template<class T>
+struct is_constructible<T>
+: is_default_constructible_helper<T>
+{};
+
+}
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/detail/join.hpp b/boost/hof/detail/join.hpp
new file mode 100644
index 0000000000..23ed8437d3
--- /dev/null
+++ b/boost/hof/detail/join.hpp
@@ -0,0 +1,43 @@
+/*=============================================================================
+ Copyright (c) 2012 Paul Fultz II
+ join.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FUNCTION_DETAIL_JOIN_H
+#define BOOST_HOF_GUARD_FUNCTION_DETAIL_JOIN_H
+
+#include <boost/hof/detail/holder.hpp>
+
+namespace boost { namespace hof { namespace detail {
+
+template<class... Ts>
+struct join_args
+{};
+
+template<template <class...> class T, class Args, class=void>
+struct join_impl
+{};
+
+template<template <class...> class T, class... Args>
+struct join_impl<T, join_args<Args...>, typename holder<
+ T<Args...>
+>::type>
+{ typedef T<Args...> type; };
+
+template<template <class...> class T, class... Args>
+struct join
+: join_impl<T, join_args<Args...>>
+{};
+
+}}} // namespace boost::hof
+
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7
+#define BOOST_HOF_JOIN(c, ...) typename boost::hof::detail::join<c, __VA_ARGS__>::type
+#else
+#define BOOST_HOF_JOIN(c, ...) c<__VA_ARGS__>
+
+#endif
+
+#endif
diff --git a/boost/hof/detail/make.hpp b/boost/hof/detail/make.hpp
new file mode 100644
index 0000000000..791e1283a2
--- /dev/null
+++ b/boost/hof/detail/make.hpp
@@ -0,0 +1,31 @@
+/*=============================================================================
+ Copyright (c) 2015 Paul Fultz II
+ make.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_MAKE_H
+#define BOOST_HOF_GUARD_MAKE_H
+
+#include <boost/hof/detail/move.hpp>
+#include <boost/hof/detail/join.hpp>
+#include <boost/hof/detail/delegate.hpp>
+
+namespace boost { namespace hof { namespace detail {
+
+template<template<class...> class Adaptor>
+struct make
+{
+ constexpr make() noexcept
+ {}
+ template<class... Fs, class Result=BOOST_HOF_JOIN(Adaptor, Fs...)>
+ constexpr Result operator()(Fs... fs) const BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(Result, Fs&&...)
+ {
+ return Result(static_cast<Fs&&>(fs)...);
+ }
+};
+
+}}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/detail/move.hpp b/boost/hof/detail/move.hpp
new file mode 100644
index 0000000000..bdbf73ddc7
--- /dev/null
+++ b/boost/hof/detail/move.hpp
@@ -0,0 +1,24 @@
+/*=============================================================================
+ Copyright (c) 2014 Paul Fultz II
+ move.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_MOVE_H
+#define BOOST_HOF_GUARD_MOVE_H
+
+#include <utility>
+
+namespace boost { namespace hof {
+
+template<typename T>
+constexpr typename std::remove_reference<T>::type&&
+move(T&& x) noexcept
+{
+ return static_cast<typename std::remove_reference<T>::type&&>(x);
+}
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/detail/noexcept.hpp b/boost/hof/detail/noexcept.hpp
new file mode 100644
index 0000000000..c7078a8b27
--- /dev/null
+++ b/boost/hof/detail/noexcept.hpp
@@ -0,0 +1,19 @@
+/*=============================================================================
+ Copyright (c) 2016 Paul Fultz II
+ noexcept.hpp
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_DETAIL_NOEXCEPT_HPP
+#define BOOST_HOF_GUARD_DETAIL_NOEXCEPT_HPP
+
+#include <boost/hof/config.hpp>
+
+#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION
+#define BOOST_HOF_NOEXCEPT(...) noexcept(__VA_ARGS__)
+#else
+#define BOOST_HOF_NOEXCEPT(...)
+#endif
+
+#endif
diff --git a/boost/hof/detail/pp.hpp b/boost/hof/detail/pp.hpp
new file mode 100644
index 0000000000..20bc7a960e
--- /dev/null
+++ b/boost/hof/detail/pp.hpp
@@ -0,0 +1,93 @@
+/*=============================================================================
+ Copyright (c) 2014 Paul Fultz II
+ pp.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_PP_H
+#define BOOST_HOF_GUARD_PP_H
+
+#define BOOST_HOF_PP_CAT(x, y) BOOST_HOF_PP_PRIMITIVE_CAT(x, y)
+#define BOOST_HOF_PP_PRIMITIVE_CAT(x, y) x ## y
+
+#define BOOST_HOF_PP_SEQ_ITERATE(...) BOOST_HOF_PP_PRIMITIVE_SEQ_ITERATE(__VA_ARGS__)
+#define BOOST_HOF_PP_PRIMITIVE_SEQ_ITERATE(...) __VA_ARGS__ ## _END
+
+//
+// BOOST_HOF_PP_NARGS returns the number of args in __VA_ARGS__
+//
+#define BOOST_HOF_PP_NARGS(...) \
+ BOOST_HOF_PP_DETAIL_NARG((__VA_ARGS__,BOOST_HOF_PP_DETAIL_RSEQ_N()))
+
+#define BOOST_HOF_PP_DETAIL_NARG(args) \
+ BOOST_HOF_PP_DETAIL_ARG_N args
+
+#define BOOST_HOF_PP_DETAIL_ARG_N( \
+ _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
+ _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
+ _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
+ _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
+ _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
+ _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
+ _61,_62,_63,N,...) N
+#define BOOST_HOF_PP_DETAIL_RSEQ_N() \
+ 63,62,61,60, \
+ 59,58,57,56,55,54,53,52,51,50, \
+ 49,48,47,46,45,44,43,42,41,40, \
+ 39,38,37,36,35,34,33,32,31,30, \
+ 29,28,27,26,25,24,23,22,21,20, \
+ 19,18,17,16,15,14,13,12,11,10, \
+ 9,8,7,6,5,4,3,2,1,0
+
+
+//
+// BOOST_HOF_PP_IS_PAREN is used to detect if the first token is a parenthesis.
+// It expands to 1 if it is, otherwise it expands to 0.
+//
+#define BOOST_HOF_PP_IS_PAREN(x) BOOST_HOF_PP_IS_PAREN_CHECK(BOOST_HOF_PP_IS_PAREN_PROBE x)
+#define BOOST_HOF_PP_IS_PAREN_CHECK(...) BOOST_HOF_PP_IS_PAREN_CHECK_N(__VA_ARGS__,0)
+#define BOOST_HOF_PP_IS_PAREN_PROBE(...) ~, 1,
+#ifndef _MSC_VER
+#define BOOST_HOF_PP_IS_PAREN_CHECK_N(x, n, ...) n
+#else
+// MSVC workarounds
+#define BOOST_HOF_PP_IS_PAREN_CHECK_RES(x) x
+#define BOOST_HOF_PP_IS_PAREN_CHECK_II(x, n, ...) n
+#define BOOST_HOF_PP_IS_PAREN_CHECK_I(x) BOOST_HOF_PP_IS_PAREN_CHECK_RES(BOOST_HOF_PP_IS_PAREN_CHECK_II x)
+#define BOOST_HOF_PP_IS_PAREN_CHECK_N(...) BOOST_HOF_PP_IS_PAREN_CHECK_I((__VA_ARGS__))
+#endif
+
+//
+// BOOST_HOF_PP_IS_1 is used to detect if the first token is a 1.
+// It expands to 1 if it is, otherwise it expands to 0.
+//
+#define BOOST_HOF_PP_IS_1(x) BOOST_HOF_PP_IS_PAREN(BOOST_HOF_PP_CAT(BOOST_HOF_PP_IS_1_PROBE_, x))
+#define BOOST_HOF_PP_IS_1_PROBE_1 ()
+
+#define BOOST_HOF_PP_ARGS_IS_SINGLE(...) BOOST_HOF_PP_IS_1(BOOST_HOF_PP_NARGS(__VA_ARGS__))
+
+#define BOOST_HOF_PP_EMPTY(...)
+#define BOOST_HOF_PP_DEFER(...) __VA_ARGS__ BOOST_HOF_PP_EMPTY()
+#define BOOST_HOF_PP_OBSTRUCT(...) __VA_ARGS__ BOOST_HOF_PP_DEFER(BOOST_HOF_PP_EMPTY)()
+#define BOOST_HOF_PP_EXPAND(...) __VA_ARGS__
+
+#define BOOST_HOF_PP_IIF(c) BOOST_HOF_PP_PRIMITIVE_CAT(BOOST_HOF_PP_IIF_, c)
+#define BOOST_HOF_PP_IIF_0(t, ...) __VA_ARGS__
+#define BOOST_HOF_PP_IIF_1(t, ...) t
+
+#define BOOST_HOF_PP_WALL(...) __VA_ARGS__
+
+#define BOOST_HOF_PP_RAIL_IIF(c) BOOST_HOF_PP_PRIMITIVE_CAT(BOOST_HOF_PP_RAIL_IIF_, c)
+#define BOOST_HOF_PP_RAIL_IIF_0(t, ...) __VA_ARGS__
+#define BOOST_HOF_PP_RAIL_IIF_1(t, ...) t
+
+#define BOOST_HOF_PP_RAIL(macro) \
+ BOOST_HOF_PP_RAIL_IIF(BOOST_HOF_PP_IS_PAREN(BOOST_HOF_PP_WALL(())))( \
+ BOOST_HOF_PP_RAIL_ID BOOST_HOF_PP_OBSTRUCT()()(macro), \
+ macro BOOST_HOF_PP_OBSTRUCT() \
+ )
+
+#define BOOST_HOF_PP_RAIL_ID() BOOST_HOF_PP_RAIL
+
+#endif
diff --git a/boost/hof/detail/recursive_constexpr_depth.hpp b/boost/hof/detail/recursive_constexpr_depth.hpp
new file mode 100644
index 0000000000..1f4e630d35
--- /dev/null
+++ b/boost/hof/detail/recursive_constexpr_depth.hpp
@@ -0,0 +1,19 @@
+/*=============================================================================
+ Copyright (c) 2016 Paul Fultz II
+ recursive_constexpr_depth.hpp
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_RECURSIVE_CONSTEXPR_DEPTH_HPP
+#define BOOST_HOF_GUARD_RECURSIVE_CONSTEXPR_DEPTH_HPP
+
+#ifndef BOOST_HOF_RECURSIVE_CONSTEXPR_DEPTH
+#define BOOST_HOF_RECURSIVE_CONSTEXPR_DEPTH 16
+#endif
+
+namespace boost { namespace hof {
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/detail/remove_rvalue_reference.hpp b/boost/hof/detail/remove_rvalue_reference.hpp
new file mode 100644
index 0000000000..7de2879eaf
--- /dev/null
+++ b/boost/hof/detail/remove_rvalue_reference.hpp
@@ -0,0 +1,26 @@
+/*=============================================================================
+ Copyright (c) 2014 Paul Fultz II
+ remove_rvalue_reference.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FUNCTION_REMOVE_RVALUE_REFERENCE_H
+#define BOOST_HOF_GUARD_FUNCTION_REMOVE_RVALUE_REFERENCE_H
+
+namespace boost { namespace hof { namespace detail {
+
+template<class T>
+struct remove_rvalue_reference
+{
+ typedef T type;
+};
+
+template<class T>
+struct remove_rvalue_reference<T&&>
+: remove_rvalue_reference<T>
+{};
+
+}}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/detail/result_of.hpp b/boost/hof/detail/result_of.hpp
new file mode 100644
index 0000000000..6beccb9d2d
--- /dev/null
+++ b/boost/hof/detail/result_of.hpp
@@ -0,0 +1,82 @@
+/*=============================================================================
+ Copyright (c) 2015 Paul Fultz II
+ result_of.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_DETAIL_RESULT_OF_H
+#define BOOST_HOF_GUARD_DETAIL_RESULT_OF_H
+
+#include <boost/hof/returns.hpp>
+#include <boost/hof/config.hpp>
+
+#if BOOST_HOF_HAS_MANUAL_DEDUCTION || BOOST_HOF_NO_EXPRESSION_SFINAE
+
+#include <boost/hof/detail/and.hpp>
+#include <boost/hof/detail/holder.hpp>
+#include <boost/hof/detail/can_be_called.hpp>
+
+namespace boost { namespace hof { namespace detail {
+
+template<class F, class Args, class=void>
+struct result_of_impl {};
+
+template<class F, class... Ts>
+struct result_of_impl<
+ F,
+ holder<Ts...>,
+ typename std::enable_if<can_be_called<F, typename Ts::type...>::value>::type
+>
+{
+ typedef decltype(std::declval<F>()(std::declval<typename Ts::type>()...)) type;
+};
+}
+
+template<class T>
+struct id_
+{
+ typedef T type;
+};
+
+template<class F, class... Ts>
+struct result_of
+: detail::result_of_impl<F, detail::holder<Ts...>>
+{};
+
+// template<class F, class... Ts>
+// using result_of = detail::result_of_impl<F, detail::holder<Ts...>>;
+// using result_of = id_<decltype(std::declval<F>()(std::declval<typename Ts::type>()...))>;
+
+}} // namespace boost::hof
+#endif
+
+#if BOOST_HOF_NO_EXPRESSION_SFINAE
+
+#define BOOST_HOF_SFINAE_RESULT(...) typename boost::hof::result_of<__VA_ARGS__>::type
+#define BOOST_HOF_SFINAE_RETURNS(...) BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(__VA_ARGS__) { return __VA_ARGS__; }
+
+#else
+
+#define BOOST_HOF_SFINAE_RESULT(...) auto
+#define BOOST_HOF_SFINAE_RETURNS BOOST_HOF_RETURNS
+
+#endif
+
+#if BOOST_HOF_HAS_MANUAL_DEDUCTION
+
+#define BOOST_HOF_SFINAE_MANUAL_RESULT(...) typename boost::hof::result_of<__VA_ARGS__>::type
+#if BOOST_HOF_HAS_COMPLETE_DECLTYPE && BOOST_HOF_HAS_MANGLE_OVERLOAD
+#define BOOST_HOF_SFINAE_MANUAL_RETURNS(...) BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(__VA_ARGS__) { return (__VA_ARGS__); }
+#else
+#define BOOST_HOF_SFINAE_MANUAL_RETURNS(...) BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(__VA_ARGS__) { BOOST_HOF_RETURNS_RETURN(__VA_ARGS__); }
+#endif
+
+#else
+
+#define BOOST_HOF_SFINAE_MANUAL_RESULT BOOST_HOF_SFINAE_RESULT
+#define BOOST_HOF_SFINAE_MANUAL_RETURNS BOOST_HOF_SFINAE_RETURNS
+
+#endif
+
+#endif
diff --git a/boost/hof/detail/result_type.hpp b/boost/hof/detail/result_type.hpp
new file mode 100644
index 0000000000..ce570baab6
--- /dev/null
+++ b/boost/hof/detail/result_type.hpp
@@ -0,0 +1,43 @@
+/*=============================================================================
+ Copyright (c) 2016 Paul Fultz II
+ result_type.hpp
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_RESULT_TYPE_HPP
+#define BOOST_HOF_GUARD_RESULT_TYPE_HPP
+
+#include <boost/hof/detail/holder.hpp>
+#include <utility>
+
+namespace boost { namespace hof { namespace detail {
+
+template<class F, class=void>
+struct function_result_type
+{};
+
+template<class F>
+struct function_result_type<F, typename holder<
+ typename F::result_type
+>::type>
+{
+ typedef typename F::result_type result_type;
+};
+
+template<class F, class G, class=void>
+struct compose_function_result_type
+: function_result_type<F>
+{};
+
+template<class F, class G>
+struct compose_function_result_type<F, G, typename holder<
+ decltype(std::declval<F>()(std::declval<typename G::result_type>()))
+>::type>
+{
+ typedef decltype(std::declval<F>()(std::declval<typename G::result_type>())) result_type;
+};
+
+}}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/detail/seq.hpp b/boost/hof/detail/seq.hpp
new file mode 100644
index 0000000000..9f9f686c1a
--- /dev/null
+++ b/boost/hof/detail/seq.hpp
@@ -0,0 +1,46 @@
+/*=============================================================================
+ Copyright (c) 2012 Paul Fultz II
+ seq.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FUNCTION_DETAIL_SEQ_H
+#define BOOST_HOF_GUARD_FUNCTION_DETAIL_SEQ_H
+
+#include <cstdlib>
+
+namespace boost { namespace hof {
+
+namespace detail {
+
+template<std::size_t ...>
+struct seq
+{
+ typedef seq type;
+};
+
+template <class, class>
+struct merge_seq;
+
+template <size_t... Xs, size_t... Ys>
+struct merge_seq<seq<Xs...>, seq<Ys...>>
+: seq<Xs..., (sizeof...(Xs)+Ys)...>
+{};
+
+template<std::size_t N>
+struct gens
+: merge_seq<
+ typename gens<N/2>::type,
+ typename gens<N - N/2>::type
+>
+{};
+
+template<> struct gens<0> : seq<> {};
+template<> struct gens<1> : seq<0> {};
+
+
+}
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/detail/static_const_var.hpp b/boost/hof/detail/static_const_var.hpp
new file mode 100644
index 0000000000..553bd23294
--- /dev/null
+++ b/boost/hof/detail/static_const_var.hpp
@@ -0,0 +1,68 @@
+/*=============================================================================
+ Copyright (c) 2015 Paul Fultz II
+ static_const_var.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_STATIC_CONST_H
+#define BOOST_HOF_GUARD_STATIC_CONST_H
+
+#include <boost/hof/detail/intrinsics.hpp>
+
+namespace boost { namespace hof { namespace detail {
+
+template<class T>
+struct static_const_storage
+{
+ static constexpr T value = T();
+};
+
+template<class T>
+constexpr T static_const_storage<T>::value;
+
+struct static_const_var_factory
+{
+ constexpr static_const_var_factory()
+ {}
+
+ template<class T>
+ constexpr const T& operator=(const T&) const
+ {
+ static_assert(BOOST_HOF_IS_DEFAULT_CONSTRUCTIBLE(T), "Static const variable must be default constructible");
+ return static_const_storage<T>::value;
+ }
+};
+}
+
+template<class T>
+constexpr const T& static_const_var()
+{
+ return detail::static_const_storage<T>::value;
+}
+
+
+}} // namespace boost::hof
+
+#if BOOST_HOF_HAS_RELAXED_CONSTEXPR || defined(_MSC_VER)
+#define BOOST_HOF_STATIC_CONSTEXPR const constexpr
+#else
+#define BOOST_HOF_STATIC_CONSTEXPR static constexpr
+#endif
+
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7
+#define BOOST_HOF_STATIC_AUTO_REF extern __attribute__((weak)) constexpr auto
+#else
+#define BOOST_HOF_STATIC_AUTO_REF static constexpr auto&
+#endif
+
+// On gcc 4.6 use weak variables
+#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7
+#define BOOST_HOF_STATIC_CONST_VAR(name) extern __attribute__((weak)) constexpr auto name
+#else
+#define BOOST_HOF_STATIC_CONST_VAR(name) static constexpr auto& name = boost::hof::detail::static_const_var_factory()
+#endif
+
+#define BOOST_HOF_DECLARE_STATIC_VAR(name, ...) BOOST_HOF_STATIC_CONST_VAR(name) = __VA_ARGS__{}
+
+#endif
diff --git a/boost/hof/detail/unpack_tuple.hpp b/boost/hof/detail/unpack_tuple.hpp
new file mode 100644
index 0000000000..19b0e853f8
--- /dev/null
+++ b/boost/hof/detail/unpack_tuple.hpp
@@ -0,0 +1,98 @@
+/*=============================================================================
+ Copyright (c) 2016 Paul Fultz II
+ unpack_tuple.hpp
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_UNPACK_TUPLE_HPP
+#define BOOST_HOF_GUARD_UNPACK_TUPLE_HPP
+
+#include <boost/hof/unpack_sequence.hpp>
+#include <boost/hof/returns.hpp>
+#include <boost/hof/detail/forward.hpp>
+#include <boost/hof/detail/seq.hpp>
+#include <tuple>
+#include <array>
+
+namespace boost { namespace hof {
+
+namespace detail {
+
+template<class Sequence>
+constexpr typename gens<std::tuple_size<Sequence>::value>::type
+make_tuple_gens(const Sequence&)
+{
+ return {};
+}
+
+#if (defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7)
+
+template<std::size_t I, class Tuple>
+struct tuple_element_return
+: std::tuple_element<I, Tuple>
+{};
+
+template<std::size_t I, class Tuple>
+struct tuple_element_return<I, Tuple&>
+: std::add_lvalue_reference<typename tuple_element_return<I, Tuple>::type>
+{};
+
+template<std::size_t I, class Tuple>
+struct tuple_element_return<I, Tuple&&>
+: std::add_rvalue_reference<typename tuple_element_return<I, Tuple>::type>
+{};
+
+template<std::size_t I, class Tuple>
+struct tuple_element_return<I, const Tuple>
+: std::add_const<typename tuple_element_return<I, Tuple>::type>
+{};
+
+template< std::size_t I, class Tuple, class R = typename tuple_element_return<I, Tuple&&>::type >
+R tuple_get( Tuple&& t )
+{
+ return (R&&)(std::get<I>(boost::hof::forward<Tuple>(t)));
+}
+#define BOOST_HOF_UNPACK_TUPLE_GET boost::hof::detail::tuple_get
+#else
+#define BOOST_HOF_UNPACK_TUPLE_GET std::get
+
+#endif
+
+template<class F, class T, std::size_t ...N>
+constexpr auto unpack_tuple(F&& f, T&& t, seq<N...>) BOOST_HOF_RETURNS
+(
+ f(
+ BOOST_HOF_AUTO_FORWARD(BOOST_HOF_UNPACK_TUPLE_GET<N>(BOOST_HOF_AUTO_FORWARD(t)))...
+ )
+);
+
+struct unpack_tuple_apply
+{
+ template<class F, class S>
+ constexpr static auto apply(F&& f, S&& t) BOOST_HOF_RETURNS
+ (
+ boost::hof::detail::unpack_tuple(BOOST_HOF_FORWARD(F)(f), BOOST_HOF_FORWARD(S)(t), boost::hof::detail::make_tuple_gens(t))
+ );
+};
+
+}
+
+template<class... Ts>
+struct unpack_sequence<std::tuple<Ts...>>
+: detail::unpack_tuple_apply
+{};
+
+template<class T, class U>
+struct unpack_sequence<std::pair<T, U>>
+: detail::unpack_tuple_apply
+{};
+
+template<class T, std::size_t N>
+struct unpack_sequence<std::array<T, N>>
+: detail::unpack_tuple_apply
+{};
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/detail/unwrap.hpp b/boost/hof/detail/unwrap.hpp
new file mode 100644
index 0000000000..c9361d891e
--- /dev/null
+++ b/boost/hof/detail/unwrap.hpp
@@ -0,0 +1,29 @@
+/*=============================================================================
+ Copyright (c) 2014 Paul Fultz II
+ unwrap.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_UNWRAP_H
+#define BOOST_HOF_GUARD_UNWRAP_H
+
+#include <type_traits>
+#include <functional>
+
+namespace boost { namespace hof { namespace detail {
+
+template <class T>
+struct unwrap_reference
+{
+ typedef T type;
+};
+template <class T>
+struct unwrap_reference<std::reference_wrapper<T>>
+{
+ typedef T& type;
+};
+
+}}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/detail/using.hpp b/boost/hof/detail/using.hpp
new file mode 100644
index 0000000000..1f320d8337
--- /dev/null
+++ b/boost/hof/detail/using.hpp
@@ -0,0 +1,21 @@
+/*=============================================================================
+ Copyright (c) 2016 Paul Fultz II
+ using.hpp
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_USING_HPP
+#define BOOST_HOF_GUARD_USING_HPP
+
+#include <boost/hof/config.hpp>
+
+#if BOOST_HOF_HAS_TEMPLATE_ALIAS
+#define BOOST_HOF_USING(name, ...) using name = __VA_ARGS__
+#define BOOST_HOF_USING_TYPENAME(name, ...) using name = typename __VA_ARGS__
+#else
+#define BOOST_HOF_USING(name, ...) struct name : std::enable_if<true, __VA_ARGS__>::type {}
+#define BOOST_HOF_USING_TYPENAME(name, ...) struct name : __VA_ARGS__ {}
+#endif
+
+#endif
diff --git a/boost/hof/eval.hpp b/boost/hof/eval.hpp
new file mode 100644
index 0000000000..dcfb6b3ab5
--- /dev/null
+++ b/boost/hof/eval.hpp
@@ -0,0 +1,86 @@
+/*=============================================================================
+ Copyright (c) 2015 Paul Fultz II
+ eval.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_EVAL_H
+#define BOOST_HOF_GUARD_EVAL_H
+
+/// eval
+/// ====
+///
+/// Description
+/// -----------
+///
+/// The `eval` function will evaluate a "thunk". This can be either a nullary
+/// function or it can be a unary function that takes the identity function as
+/// the first parameter(which is helpful to delay compile-time checking).
+/// Also, additional parameters can be passed to `eval` to delay
+/// compiliation(so that result can depend on template parameters).
+///
+/// Synopsis
+/// --------
+///
+/// template<class F, class... Ts>
+/// constexpr auto eval(F&& f, Ts&&...);
+///
+/// Requirements
+/// ------------
+///
+/// F must be:
+///
+/// * [EvaluatableFunctionObject](EvaluatableFunctionObject)
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+///
+/// int main() {
+/// assert(boost::hof::eval([]{ return 3; }) == 3);
+/// }
+///
+/// References
+/// ----------
+///
+/// * [POO51](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0051r2.pdf) - Proposal for C++
+/// Proposal for C++ generic overload function
+/// * [static_if](static_if)
+/// * [Ordering evaluation of arguments](<Ordering evaluation of arguments>)
+///
+
+#include <boost/hof/always.hpp>
+#include <boost/hof/identity.hpp>
+#include <boost/hof/first_of.hpp>
+#include <boost/hof/detail/result_of.hpp>
+
+namespace boost { namespace hof {
+
+namespace detail {
+
+struct simple_eval
+{
+ template<class F, class... Ts>
+ constexpr BOOST_HOF_SFINAE_RESULT(F)
+ operator()(F&& f, Ts&&...xs) const BOOST_HOF_SFINAE_RETURNS
+ (boost::hof::always_ref(f)(xs...)());
+};
+
+struct id_eval
+{
+ template<class F, class... Ts>
+ constexpr BOOST_HOF_SFINAE_RESULT(F, id_<decltype(boost::hof::identity)>)
+ operator()(F&& f, Ts&&...xs) const BOOST_HOF_SFINAE_RETURNS
+ (boost::hof::always_ref(f)(xs...)(boost::hof::identity));
+};
+
+}
+
+BOOST_HOF_DECLARE_STATIC_VAR(eval, boost::hof::first_of_adaptor<detail::simple_eval, detail::id_eval>);
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/first_of.hpp b/boost/hof/first_of.hpp
new file mode 100644
index 0000000000..83edf49e6d
--- /dev/null
+++ b/boost/hof/first_of.hpp
@@ -0,0 +1,244 @@
+/*=============================================================================
+ Copyright (c) 2012 Paul Fultz II
+ first_of.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FUNCTION_CONDITIONAL_H
+#define BOOST_HOF_GUARD_FUNCTION_CONDITIONAL_H
+
+/// first_of
+/// ========
+///
+/// Description
+/// -----------
+///
+/// The `first_of` function adaptor combines several functions together. If
+/// the first function can not be called, then it will try to call the next
+/// function. This can be very useful when overloading functions using
+/// template constraints(such as with `enable_if`).
+///
+/// Note: This is different than the [`match`](match.md) function adaptor, which
+/// can lead to ambiguities. Instead, `first_of` will call the first function
+/// that is callable, regardless if there is another function that could be
+/// called as well.
+///
+/// Synopsis
+/// --------
+///
+/// template<class... Fs>
+/// constexpr first_of_adaptor<Fs...> first_of(Fs... fs);
+///
+/// Requirements
+/// ------------
+///
+/// Fs must be:
+///
+/// * [ConstInvocable](ConstInvocable)
+/// * MoveConstructible
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <iostream>
+/// using namespace boost::hof;
+///
+/// struct for_ints
+/// {
+/// void operator()(int) const
+/// {
+/// printf("Int\n");
+/// }
+/// };
+///
+/// struct for_floats
+/// {
+/// void operator()(float) const
+/// {
+/// printf("Float\n");
+/// }
+/// };
+///
+/// int main() {
+/// first_of(for_ints(), for_floats())(3.0);
+/// }
+///
+/// This will print `Int` because the `for_floats` function object won't ever be
+/// called. Due to the conversion rules in C++, the `for_ints` function can be
+/// called on floats, so it is chosen by `first_of` first, even though
+/// `for_floats` is a better match.
+///
+/// So, the order of the functions in the `first_of_adaptor` are very important
+/// to how the function is chosen.
+///
+/// References
+/// ----------
+///
+/// * [POO51](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0051r2.pdf) - Proposal for C++
+/// Proposal for C++ generic overload function
+/// * [Conditional overloading](<Conditional overloading>)
+///
+
+#include <boost/hof/reveal.hpp>
+#include <boost/hof/detail/compressed_pair.hpp>
+#include <boost/hof/detail/callable_base.hpp>
+#include <boost/hof/detail/delegate.hpp>
+#include <boost/hof/detail/join.hpp>
+#include <boost/hof/detail/seq.hpp>
+#include <boost/hof/detail/make.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+
+namespace boost { namespace hof {
+
+namespace detail {
+
+template<class F1, class F2>
+struct basic_first_of_adaptor : F1, F2
+{
+ BOOST_HOF_INHERIT_DEFAULT(basic_first_of_adaptor, F1, F2)
+
+ template<class A, class B,
+ BOOST_HOF_ENABLE_IF_CONVERTIBLE(A, F1),
+ BOOST_HOF_ENABLE_IF_CONVERTIBLE(B, F2)>
+ constexpr basic_first_of_adaptor(A&& f1, B&& f2)
+ noexcept(BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(F1, A&&) && BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(F2, B&&))
+ : F1(BOOST_HOF_FORWARD(A)(f1)), F2(BOOST_HOF_FORWARD(B)(f2))
+ {}
+
+ template<class X,
+ class=typename std::enable_if<
+ BOOST_HOF_IS_CONVERTIBLE(X, F1) &&
+ BOOST_HOF_IS_DEFAULT_CONSTRUCTIBLE(F2)
+ >::type>
+ constexpr basic_first_of_adaptor(X&& x)
+ BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(F1, X&&)
+ : F1(BOOST_HOF_FORWARD(X)(x))
+ {}
+
+ template<class... Ts>
+ struct select
+ : std::conditional
+ <
+ is_invocable<F1, Ts...>::value,
+ F1,
+ F2
+ >
+ {};
+
+ BOOST_HOF_RETURNS_CLASS(basic_first_of_adaptor);
+
+ template<class... Ts, class F=typename select<Ts...>::type>
+ constexpr BOOST_HOF_SFINAE_RESULT(typename select<Ts...>::type, id_<Ts>...)
+ operator()(Ts && ... xs) const
+ BOOST_HOF_SFINAE_RETURNS
+ (
+ BOOST_HOF_RETURNS_STATIC_CAST(const F&)(*BOOST_HOF_CONST_THIS)(BOOST_HOF_FORWARD(Ts)(xs)...)
+ );
+};
+
+template <class F1, class F2>
+constexpr const F1& which(std::true_type, const F1& f1, const F2&) noexcept
+{
+ return f1;
+}
+
+template <class F1, class F2>
+constexpr const F2& which(std::false_type, const F1&, const F2& f2) noexcept
+{
+ return f2;
+}
+
+template<class F1, class F2>
+struct conditional_kernel : compressed_pair<F1, F2>
+{
+ typedef compressed_pair<F1, F2> base;
+ BOOST_HOF_INHERIT_CONSTRUCTOR(conditional_kernel, base)
+
+ template<class... Ts>
+ struct select
+ : std::conditional
+ <
+ is_invocable<F1, Ts...>::value,
+ F1,
+ F2
+ >
+ {};
+
+ BOOST_HOF_RETURNS_CLASS(conditional_kernel);
+
+ template<class... Ts, class PickFirst=is_invocable<F1, Ts...>>
+ constexpr BOOST_HOF_SFINAE_RESULT(typename select<Ts...>::type, id_<Ts>...)
+ operator()(Ts && ... xs) const
+ BOOST_HOF_SFINAE_RETURNS
+ (
+ boost::hof::detail::which(
+ BOOST_HOF_RETURNS_CONSTRUCT(PickFirst)(),
+ BOOST_HOF_MANGLE_CAST(const F1&)(BOOST_HOF_CONST_THIS->first(xs...)),
+ BOOST_HOF_MANGLE_CAST(const F2&)(BOOST_HOF_CONST_THIS->second(xs...))
+ )
+ (BOOST_HOF_FORWARD(Ts)(xs)...)
+ );
+};
+}
+
+template<class F, class... Fs>
+struct first_of_adaptor
+: detail::conditional_kernel<F, BOOST_HOF_JOIN(first_of_adaptor, Fs...) >
+{
+ typedef first_of_adaptor fit_rewritable_tag;
+ typedef BOOST_HOF_JOIN(first_of_adaptor, Fs...) kernel_base;
+ typedef detail::conditional_kernel<F, kernel_base > base;
+
+ BOOST_HOF_INHERIT_DEFAULT(first_of_adaptor, base)
+
+ template<class X, class... Xs,
+ BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(base, X, kernel_base),
+ BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(kernel_base, Xs...)>
+ constexpr first_of_adaptor(X&& f1, Xs&& ... fs)
+ noexcept(BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(base, X&&, kernel_base) && BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(kernel_base, Xs&&...))
+ : base(BOOST_HOF_FORWARD(X)(f1), kernel_base(BOOST_HOF_FORWARD(Xs)(fs)...))
+ {}
+
+ template<class X, class... Xs,
+ BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(base, X)>
+ constexpr first_of_adaptor(X&& f1)
+ BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(base, X&&)
+ : base(BOOST_HOF_FORWARD(X)(f1))
+ {}
+
+ struct failure
+ : failure_for<F, Fs...>
+ {};
+};
+
+template<class F>
+struct first_of_adaptor<F> : F
+{
+ typedef first_of_adaptor fit_rewritable_tag;
+ BOOST_HOF_INHERIT_CONSTRUCTOR(first_of_adaptor, F);
+
+ struct failure
+ : failure_for<F>
+ {};
+};
+
+template<class F1, class F2>
+struct first_of_adaptor<F1, F2>
+: detail::conditional_kernel<F1, F2>
+{
+ typedef detail::conditional_kernel<F1, F2> base;
+ typedef first_of_adaptor fit_rewritable_tag;
+ BOOST_HOF_INHERIT_CONSTRUCTOR(first_of_adaptor, base);
+
+ struct failure
+ : failure_for<F1, F2>
+ {};
+};
+
+BOOST_HOF_DECLARE_STATIC_VAR(first_of, detail::make<first_of_adaptor>);
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/fix.hpp b/boost/hof/fix.hpp
new file mode 100644
index 0000000000..24bc8dc789
--- /dev/null
+++ b/boost/hof/fix.hpp
@@ -0,0 +1,242 @@
+/*=============================================================================
+ Copyright (c) 2014 Paul Fultz II
+ fix.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FUNCTION_FIX_H
+#define BOOST_HOF_GUARD_FUNCTION_FIX_H
+
+/// fix
+/// ===
+///
+/// Description
+/// -----------
+///
+/// The `fix` function adaptor implements a fixed-point combinator. This can be
+/// used to write recursive functions.
+///
+/// When using `constexpr`, a function can recurse to a depth that is defined by
+/// `BOOST_HOF_RECURSIVE_CONSTEXPR_DEPTH`(default is 16). There is no limitiation on
+/// recursion depth for non-constexpr functions. In addition, due to the
+/// eagerness of `constexpr` to instantiation templates, in some cases, an
+/// explicit return type must be specified in order to avoid reaching the
+/// recursion limits of the compiler. This can be accomplished using
+/// [`boost::hof::result`](/include/boost/hof/result):
+///
+/// int r = boost::hof::result<int>(factorial)(5);
+///
+/// Synopsis
+/// --------
+///
+/// template<class F>
+/// constexpr fix_adaptor<F> fix(F f);
+///
+/// Semantics
+/// ---------
+///
+/// assert(fix(f)(xs...) == f(fix(f), xs...));
+///
+/// Requirements
+/// ------------
+///
+/// F must be:
+///
+/// * [ConstFunctionObject](ConstFunctionObject)
+/// * MoveConstructible
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+///
+/// int main() {
+/// auto factorial = boost::hof::fix(
+/// [](auto recurse, auto x) -> decltype(x) {
+/// return x == 0 ? 1 : x * recurse(x-1);
+/// }
+/// );
+/// int r = boost::hof::result<int>(factorial)(5);
+/// assert(r == 5*4*3*2*1);
+/// }
+///
+/// References
+/// ----------
+///
+/// * [Fixed-point combinator](https://en.wikipedia.org/wiki/Fixed-point_combinator)
+/// * [Recursive](Recursive)
+///
+
+#include <boost/hof/always.hpp>
+#include <boost/hof/detail/callable_base.hpp>
+#include <boost/hof/reveal.hpp>
+#include <boost/hof/detail/delegate.hpp>
+#include <boost/hof/detail/move.hpp>
+#include <boost/hof/detail/make.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+#include <boost/hof/indirect.hpp>
+#include <boost/hof/result.hpp>
+#include <boost/hof/detail/recursive_constexpr_depth.hpp>
+
+
+namespace boost { namespace hof {
+
+namespace detail{
+
+template<class F>
+struct compute_indirect_ref
+{ typedef indirect_adaptor<const F*> type; };
+
+template<class F>
+struct compute_indirect_ref<indirect_adaptor<F*>>
+{ typedef indirect_adaptor<F*> type; };
+
+template<class F>
+constexpr indirect_adaptor<const F*> make_indirect_ref(const F& f) noexcept
+{
+ return indirect_adaptor<const F*>(&f);
+}
+
+template<class F>
+constexpr indirect_adaptor<const F*> make_indirect_ref(const indirect_adaptor<F*>& f) noexcept
+{
+ return f;
+}
+
+template<class F, class=void>
+struct fix_result
+{
+ template<class... Ts>
+ struct apply
+ {
+ typedef decltype(std::declval<F>()(std::declval<Ts>()...)) type;
+ };
+};
+
+template<class F>
+struct fix_result<F, typename holder<
+ typename F::result_type
+>::type>
+{
+ template<class...>
+ struct apply
+ {
+ typedef typename F::result_type type;
+ };
+
+};
+
+template<class F, class Result, int N>
+struct fix_adaptor_base : F
+{
+ BOOST_HOF_INHERIT_CONSTRUCTOR(fix_adaptor_base, F);
+
+ typedef typename compute_indirect_ref<F>::type base_ref_type;
+ typedef fix_adaptor_base<base_ref_type, Result, N-1> derived;
+
+
+ template<class... Ts>
+ constexpr const F& base_function(Ts&&... xs) const noexcept
+ {
+ return boost::hof::always_ref(*this)(xs...);
+ }
+
+ template<class... Ts>
+ constexpr derived derived_function(Ts&&... xs) const noexcept
+ {
+ return derived(boost::hof::detail::make_indirect_ref(this->base_function(xs...)));
+ }
+
+ struct fix_failure
+ {
+ template<class Failure>
+ struct apply
+ {
+ template<class... Ts>
+ struct of
+ : Failure::template of<derived, Ts...>
+ {};
+ };
+ };
+
+ struct failure
+ : failure_map<fix_failure, F>
+ {};
+
+
+ BOOST_HOF_RETURNS_CLASS(fix_adaptor_base);
+
+ template<class... Ts>
+ constexpr BOOST_HOF_SFINAE_RESULT(const F&, id_<derived>, id_<Ts>...)
+ operator()(Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS
+ (
+ BOOST_HOF_MANGLE_CAST(const F&)(BOOST_HOF_CONST_THIS->base_function(xs...))
+ (
+ BOOST_HOF_MANGLE_CAST(derived)(BOOST_HOF_CONST_THIS->derived_function(xs...)),
+ BOOST_HOF_FORWARD(Ts)(xs)...
+ )
+ );
+};
+
+template<class F, class Result>
+struct fix_adaptor_base<F, Result, 0> : F
+{
+ BOOST_HOF_INHERIT_CONSTRUCTOR(fix_adaptor_base, F);
+
+ template<class... Ts>
+ const F& base_function(Ts&&...) const noexcept
+ {
+ return *this;
+ }
+
+ struct fix_failure
+ {
+ template<class Failure>
+ struct apply
+ {
+ template<class... Ts>
+ struct of
+ : Failure::template of<fix_adaptor_base, Ts...>
+ {};
+ };
+ };
+
+ struct failure
+ : failure_map<fix_failure, F>
+ {};
+
+
+ BOOST_HOF_RETURNS_CLASS(fix_adaptor_base);
+
+ template<class... Ts>
+ typename Result::template apply<fix_adaptor_base, Ts...>::type
+ operator()(Ts&&... xs) const
+ {
+ return this->base_function(xs...)(*this, BOOST_HOF_FORWARD(Ts)(xs)...);
+ }
+};
+}
+
+template<class F>
+struct fix_adaptor : detail::fix_adaptor_base<F, detail::fix_result<F>, BOOST_HOF_RECURSIVE_CONSTEXPR_DEPTH>
+{
+ typedef fix_adaptor fit_rewritable1_tag;
+ typedef detail::fix_adaptor_base<F, detail::fix_result<F>, BOOST_HOF_RECURSIVE_CONSTEXPR_DEPTH> base;
+ BOOST_HOF_INHERIT_CONSTRUCTOR(fix_adaptor, base);
+};
+
+template<class Result, class F>
+struct result_adaptor<Result, fix_adaptor<F>>
+: fix_adaptor<result_adaptor<Result, F>>
+{
+ typedef fix_adaptor<result_adaptor<Result, F>> base;
+ BOOST_HOF_INHERIT_CONSTRUCTOR(result_adaptor, base)
+};
+
+BOOST_HOF_DECLARE_STATIC_VAR(fix, detail::make<fix_adaptor>);
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/flip.hpp b/boost/hof/flip.hpp
new file mode 100644
index 0000000000..cd7a1f9174
--- /dev/null
+++ b/boost/hof/flip.hpp
@@ -0,0 +1,107 @@
+/*=============================================================================
+ Copyright (c) 2015 Paul Fultz II
+ flip.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FLIP_H
+#define BOOST_HOF_GUARD_FLIP_H
+
+/// flip
+/// ====
+///
+/// Description
+/// -----------
+///
+/// The `flip` function adaptor swaps the first two parameters.
+///
+/// Synopsis
+/// --------
+///
+/// template<class F>
+/// flip_adaptor<F> flip(F f);
+///
+/// Semantics
+/// ---------
+///
+/// assert(flip(f)(x, y, xs...) == f(y, x, xs...));
+///
+/// Requirements
+/// ------------
+///
+/// F must be at least:
+///
+/// * [BinaryInvocable](BinaryInvocable)
+///
+/// Or:
+///
+/// * [Invocable](Invocable) with more than two argurments
+///
+/// And:
+///
+/// * MoveConstructible
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+///
+/// int main() {
+/// int r = boost::hof::flip(boost::hof::_ - boost::hof::_)(2, 5);
+/// assert(r == 3);
+/// }
+///
+
+#include <boost/hof/detail/callable_base.hpp>
+#include <boost/hof/reveal.hpp>
+#include <boost/hof/detail/make.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+
+namespace boost { namespace hof {
+
+template<class F>
+struct flip_adaptor : detail::callable_base<F>
+{
+ typedef flip_adaptor fit_rewritable1_tag;
+ BOOST_HOF_INHERIT_CONSTRUCTOR(flip_adaptor, detail::callable_base<F>);
+
+ template<class... Ts>
+ constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const
+ {
+ return boost::hof::always_ref(*this)(xs...);
+ }
+
+ struct flip_failure
+ {
+ template<class Failure>
+ struct apply
+ {
+ template<class T, class U, class... Ts>
+ struct of
+ : Failure::template of<U, T, Ts...>
+ {};
+ };
+ };
+
+ struct failure
+ : failure_map<flip_failure, detail::callable_base<F>>
+ {};
+
+ BOOST_HOF_RETURNS_CLASS(flip_adaptor);
+
+ template<class T, class U, class... Ts>
+ constexpr BOOST_HOF_SFINAE_RESULT(const detail::callable_base<F>&, id_<U>, id_<T>, id_<Ts>...)
+ operator()(T&& x, U&& y, Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS
+ (
+ (BOOST_HOF_MANGLE_CAST(const detail::callable_base<F>&)(BOOST_HOF_CONST_THIS->base_function(xs...)))
+ (BOOST_HOF_FORWARD(U)(y), BOOST_HOF_FORWARD(T)(x), BOOST_HOF_FORWARD(Ts)(xs)...)
+ );
+};
+
+BOOST_HOF_DECLARE_STATIC_VAR(flip, detail::make<flip_adaptor>);
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/flow.hpp b/boost/hof/flow.hpp
new file mode 100644
index 0000000000..643189c64c
--- /dev/null
+++ b/boost/hof/flow.hpp
@@ -0,0 +1,166 @@
+/*=============================================================================
+ Copyright (c) 2015 Paul Fultz II
+ flow.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FUNCTION_FLOW_H
+#define BOOST_HOF_GUARD_FUNCTION_FLOW_H
+
+/// flow
+/// ====
+///
+/// Description
+/// -----------
+///
+/// The `flow` function adaptor provides function composition. It is useful as
+/// an alternative to using the pipe operator `|` when chaining functions. It is
+/// similiar to [`compose`](compose.md) except the evaluation order is
+/// reversed. So, `flow(f, g)(0)` is equivalent to `g(f(0))`.
+///
+///
+/// Synopsis
+/// --------
+///
+/// template<class... Fs>
+/// constexpr flow_adaptor<Fs...> flow(Fs... fs);
+///
+/// Semantics
+/// ---------
+///
+/// assert(flow(f, g)(xs...) == g(f(xs...)));
+///
+/// Requirements
+/// ------------
+///
+/// Fs must be:
+///
+/// * [ConstInvocable](ConstInvocable)
+/// * MoveConstructible
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+/// using namespace boost::hof;
+///
+/// struct increment
+/// {
+/// template<class T>
+/// T operator()(T x) const
+/// {
+/// return x + 1;
+/// }
+/// };
+///
+/// struct decrement
+/// {
+/// template<class T>
+/// T operator()(T x) const
+/// {
+/// return x - 1;
+/// }
+/// };
+///
+/// int main() {
+/// int r = flow(increment(), decrement(), increment())(3);
+/// assert(r == 4);
+/// }
+///
+/// References
+/// ----------
+///
+/// * [Function composition](https://en.wikipedia.org/wiki/Function_composition)
+///
+
+#include <boost/hof/detail/callable_base.hpp>
+#include <boost/hof/always.hpp>
+#include <boost/hof/detail/delegate.hpp>
+#include <boost/hof/detail/compressed_pair.hpp>
+#include <boost/hof/detail/join.hpp>
+#include <tuple>
+#include <boost/hof/detail/move.hpp>
+#include <boost/hof/detail/make.hpp>
+#include <boost/hof/detail/result_type.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+
+namespace boost { namespace hof { namespace detail {
+
+template<class F1, class F2>
+struct flow_kernel : detail::compressed_pair<detail::callable_base<F1>, detail::callable_base<F2>>, compose_function_result_type<F2, F1>
+{
+ typedef detail::compressed_pair<detail::callable_base<F1>, detail::callable_base<F2>> base_type;
+
+ BOOST_HOF_INHERIT_CONSTRUCTOR(flow_kernel, base_type)
+
+ BOOST_HOF_RETURNS_CLASS(flow_kernel);
+
+ template<class... Ts>
+ constexpr BOOST_HOF_SFINAE_RESULT(const detail::callable_base<F2>&, result_of<const detail::callable_base<F1>&, id_<Ts>...>)
+ operator()(Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS
+ (
+ BOOST_HOF_MANGLE_CAST(const detail::callable_base<F2>&)(BOOST_HOF_CONST_THIS->second(xs...))(
+ BOOST_HOF_MANGLE_CAST(const detail::callable_base<F1>&)(BOOST_HOF_CONST_THIS->first(xs...))(BOOST_HOF_FORWARD(Ts)(xs)...)
+ )
+ );
+};
+}
+
+template<class F, class... Fs>
+struct flow_adaptor : detail::flow_kernel<F, BOOST_HOF_JOIN(flow_adaptor, Fs...)>
+{
+ typedef flow_adaptor fit_rewritable_tag;
+ typedef BOOST_HOF_JOIN(flow_adaptor, Fs...) tail;
+ typedef detail::flow_kernel<F, tail> base_type;
+
+ BOOST_HOF_INHERIT_DEFAULT(flow_adaptor, base_type)
+
+ template<class X, class... Xs,
+ BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(detail::callable_base<F>, X),
+ BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(tail, Xs...)
+ >
+ constexpr flow_adaptor(X&& f1, Xs&& ... fs)
+ BOOST_HOF_NOEXCEPT(BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(base_type, X&&, tail) && BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(tail, Xs&&...))
+ : base_type(BOOST_HOF_FORWARD(X)(f1), tail(BOOST_HOF_FORWARD(Xs)(fs)...))
+ {}
+
+ template<class X,
+ BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(detail::callable_base<F>, X)
+ >
+ constexpr flow_adaptor(X&& f1)
+ BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(base_type, X&&)
+ : base_type(BOOST_HOF_FORWARD(X)(f1))
+ {}
+};
+
+template<class F>
+struct flow_adaptor<F> : detail::callable_base<F>
+{
+ typedef flow_adaptor fit_rewritable_tag;
+ BOOST_HOF_INHERIT_DEFAULT(flow_adaptor, detail::callable_base<F>)
+
+ template<class X, BOOST_HOF_ENABLE_IF_CONVERTIBLE(X, detail::callable_base<F>)>
+ constexpr flow_adaptor(X&& f1)
+ BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(detail::callable_base<F>, X&&)
+ : detail::callable_base<F>(BOOST_HOF_FORWARD(X)(f1))
+ {}
+
+};
+
+template<class F1, class F2>
+struct flow_adaptor<F1, F2>
+: detail::flow_kernel<detail::callable_base<F1>, detail::callable_base<F2>>
+{
+ typedef flow_adaptor fit_rewritable_tag;
+ typedef detail::flow_kernel<detail::callable_base<F1>, detail::callable_base<F2>> base_type;
+
+ BOOST_HOF_INHERIT_CONSTRUCTOR(flow_adaptor, base_type)
+};
+
+BOOST_HOF_DECLARE_STATIC_VAR(flow, detail::make<flow_adaptor>);
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/fold.hpp b/boost/hof/fold.hpp
new file mode 100644
index 0000000000..cebe7888e9
--- /dev/null
+++ b/boost/hof/fold.hpp
@@ -0,0 +1,171 @@
+/*=============================================================================
+ Copyright (c) 2015 Paul Fultz II
+ fold.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FOLD_H
+#define BOOST_HOF_GUARD_FOLD_H
+
+/// fold
+/// ========
+///
+/// Description
+/// -----------
+///
+/// The `fold` function adaptor uses a binary function to apply a
+/// [fold](https://en.wikipedia.org/wiki/Fold_%28higher-order_function%29)
+/// operation to the arguments passed to the function. Additionally, an
+/// optional initial state can be provided, otherwise the first argument is
+/// used as the initial state.
+///
+/// The arguments to the binary function, take first the state and then the
+/// argument.
+///
+/// Synopsis
+/// --------
+///
+/// template<class F, class State>
+/// constexpr fold_adaptor<F, State> fold(F f, State s);
+///
+/// template<class F>
+/// constexpr fold_adaptor<F> fold(F f);
+///
+/// Semantics
+/// ---------
+///
+/// assert(fold(f, z)() == z);
+/// assert(fold(f, z)(x, xs...) == fold(f, f(z, x))(xs...));
+/// assert(fold(f)(x) == x);
+/// assert(fold(f)(x, y, xs...) == fold(f)(f(x, y), xs...));
+///
+/// Requirements
+/// ------------
+///
+/// State must be:
+///
+/// * CopyConstructible
+///
+/// F must be:
+///
+/// * [BinaryInvocable](BinaryInvocable)
+/// * MoveConstructible
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+///
+/// struct max_f
+/// {
+/// template<class T, class U>
+/// constexpr T operator()(T x, U y) const
+/// {
+/// return x > y ? x : y;
+/// }
+/// };
+/// int main() {
+/// assert(boost::hof::fold(max_f())(2, 3, 4, 5) == 5);
+/// }
+///
+/// References
+/// ----------
+///
+/// * [Fold](https://en.wikipedia.org/wiki/Fold_(higher-order_function))
+/// * [Variadic sum](<Variadic sum>)
+///
+
+#include <boost/hof/detail/callable_base.hpp>
+#include <boost/hof/detail/delegate.hpp>
+#include <boost/hof/detail/compressed_pair.hpp>
+#include <boost/hof/detail/move.hpp>
+#include <boost/hof/detail/make.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+
+namespace boost { namespace hof { namespace detail {
+
+struct v_fold
+{
+ BOOST_HOF_RETURNS_CLASS(v_fold);
+ template<class F, class State, class T, class... Ts>
+ constexpr BOOST_HOF_SFINAE_MANUAL_RESULT(const v_fold&, id_<const F&>, result_of<const F&, id_<State>, id_<T>>, id_<Ts>...)
+ operator()(const F& f, State&& state, T&& x, Ts&&... xs) const BOOST_HOF_SFINAE_MANUAL_RETURNS
+ (
+ (*BOOST_HOF_CONST_THIS)(f, f(BOOST_HOF_FORWARD(State)(state), BOOST_HOF_FORWARD(T)(x)), BOOST_HOF_FORWARD(Ts)(xs)...)
+ );
+
+ template<class F, class State>
+ constexpr State operator()(const F&, State&& state) const noexcept
+ {
+ return BOOST_HOF_FORWARD(State)(state);
+ }
+};
+
+}
+
+template<class F, class State=void>
+struct fold_adaptor
+: detail::compressed_pair<detail::callable_base<F>, State>
+{
+ typedef detail::compressed_pair<detail::callable_base<F>, State> base_type;
+ BOOST_HOF_INHERIT_CONSTRUCTOR(fold_adaptor, base_type)
+
+ template<class... Ts>
+ constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const noexcept
+ {
+ return this->first(xs...);
+ }
+
+ template<class... Ts>
+ constexpr State get_state(Ts&&... xs) const noexcept
+ {
+ return this->second(xs...);
+ }
+
+ BOOST_HOF_RETURNS_CLASS(fold_adaptor);
+
+ template<class... Ts>
+ constexpr BOOST_HOF_SFINAE_RESULT(detail::v_fold, id_<const detail::callable_base<F>&>, id_<State>, id_<Ts>...)
+ operator()(Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS
+ (
+ detail::v_fold()(
+ BOOST_HOF_MANGLE_CAST(const detail::callable_base<F>&)(BOOST_HOF_CONST_THIS->base_function(xs...)),
+ BOOST_HOF_MANGLE_CAST(State)(BOOST_HOF_CONST_THIS->get_state(xs...)),
+ BOOST_HOF_FORWARD(Ts)(xs)...
+ )
+ )
+};
+
+
+template<class F>
+struct fold_adaptor<F, void>
+: detail::callable_base<F>
+{
+ BOOST_HOF_INHERIT_CONSTRUCTOR(fold_adaptor, detail::callable_base<F>)
+
+ template<class... Ts>
+ constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const noexcept
+ {
+ return boost::hof::always_ref(*this)(xs...);
+ }
+
+ BOOST_HOF_RETURNS_CLASS(fold_adaptor);
+
+ template<class... Ts>
+ constexpr BOOST_HOF_SFINAE_RESULT(detail::v_fold, id_<const detail::callable_base<F>&>, id_<Ts>...)
+ operator()(Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS
+ (
+ detail::v_fold()(
+ BOOST_HOF_MANGLE_CAST(const detail::callable_base<F>&)(BOOST_HOF_CONST_THIS->base_function(xs...)),
+ BOOST_HOF_FORWARD(Ts)(xs)...
+ )
+ )
+};
+
+BOOST_HOF_DECLARE_STATIC_VAR(fold, detail::make<fold_adaptor>);
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/function.hpp b/boost/hof/function.hpp
new file mode 100644
index 0000000000..6693e8d236
--- /dev/null
+++ b/boost/hof/function.hpp
@@ -0,0 +1,90 @@
+/*=============================================================================
+ Copyright (c) 2014 Paul Fultz II
+ function.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FUNCTION_FUNCTION_H
+#define BOOST_HOF_GUARD_FUNCTION_FUNCTION_H
+
+/// BOOST_HOF_STATIC_FUNCTION
+/// ===================
+///
+/// Description
+/// -----------
+///
+
+/// The `BOOST_HOF_STATIC_FUNCTION` macro allows initializing a function object from a
+/// `constexpr` expression. It uses the best practices as outlined in
+/// [N4381](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html).
+/// This includes using `const` to avoid global state, compile-time
+/// initialization of the function object to avoid the [static initialization
+/// order fiasco](https://isocpp.org/wiki/faq/ctors#static-init-order), and an
+/// external address of the function object that is the same across translation
+/// units to avoid possible One-Definition-Rule(ODR) violations.
+///
+/// In C++17, this achieved using the `inline` keyword. However, on older
+/// compilers it is initialized using a reference to a static member variable.
+/// The static member variable is default constructed, as such the user variable
+/// is always default constructed regardless of the expression.
+///
+/// By default, all functions defined with `BOOST_HOF_STATIC_FUNCTION` use the
+/// [`boost::hof::reveal`](/include/boost/hof/reveal) adaptor to improve error messages.
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+///
+/// struct sum_f
+/// {
+/// template<class T, class U>
+/// T operator()(T x, U y) const
+/// {
+/// return x+y;
+/// }
+/// };
+///
+/// BOOST_HOF_STATIC_FUNCTION(sum) = sum_f();
+/// BOOST_HOF_STATIC_FUNCTION(partial_sum) = boost::hof::partial(sum_f());
+///
+/// int main() {
+/// assert(sum(1, 2) == partial_sum(1)(2));
+/// }
+///
+
+#include <boost/hof/reveal.hpp>
+#if !BOOST_HOF_HAS_INLINE_VARIABLES
+#include <boost/hof/detail/static_const_var.hpp>
+#include <boost/hof/detail/constexpr_deduce.hpp>
+#endif
+
+namespace boost { namespace hof {
+
+namespace detail {
+
+struct reveal_static_const_factory
+{
+ constexpr reveal_static_const_factory()
+ {}
+ template<class F>
+ constexpr reveal_adaptor<F> operator=(const F& f) const
+ {
+#if BOOST_HOF_HAS_INLINE_VARIABLES
+#else
+ static_assert(BOOST_HOF_IS_DEFAULT_CONSTRUCTIBLE(F), "Static functions must be default constructible");
+#endif
+ return reveal_adaptor<F>(f);
+ }
+};
+}}} // namespace boost::hof
+
+#if BOOST_HOF_HAS_INLINE_VARIABLES
+#define BOOST_HOF_STATIC_FUNCTION(name) inline const constexpr auto name = boost::hof::detail::reveal_static_const_factory()
+#else
+#define BOOST_HOF_STATIC_FUNCTION(name) BOOST_HOF_STATIC_CONST_VAR(name) = BOOST_HOF_DETAIL_MSVC_CONSTEXPR_DEDUCE boost::hof::detail::reveal_static_const_factory()
+#endif
+
+#endif
diff --git a/boost/hof/function_param_limit.hpp b/boost/hof/function_param_limit.hpp
new file mode 100644
index 0000000000..cf6e2238c2
--- /dev/null
+++ b/boost/hof/function_param_limit.hpp
@@ -0,0 +1,57 @@
+/*=============================================================================
+ Copyright (c) 2016 Paul Fultz II
+ function_param_limit.hpp
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FUNCTION_PARAM_LIMIT_HPP
+#define BOOST_HOF_GUARD_FUNCTION_PARAM_LIMIT_HPP
+
+/// function_param_limit
+/// ====================
+///
+/// Description
+/// -----------
+///
+/// The `function_param_limit` metafunction retrieves the maximum number of
+/// parameters for a function. For function pointers it returns the number of
+/// parameters. Everything else, it returns `SIZE_MAX`, but this can be
+/// changed by annotating the function with the [`limit`](limit) decorator.
+///
+/// This is a type trait that inherits from `std::integral_constant`.
+///
+/// Synopsis
+/// --------
+///
+/// template<class F>
+/// struct function_param_limit
+/// : std::integral_constant<std::size_t, ...>
+/// {};
+///
+/// See Also
+/// --------
+///
+/// * [Partial function evaluation](<Partial function evaluation>)
+/// * [limit](limit)
+///
+
+#include <boost/hof/detail/holder.hpp>
+#include <type_traits>
+#include <cstdint>
+
+namespace boost { namespace hof {
+
+template<class F, class=void>
+struct function_param_limit
+: std::integral_constant<std::size_t, SIZE_MAX>
+{};
+
+template<class F>
+struct function_param_limit<F, typename detail::holder<typename F::fit_function_param_limit>::type>
+: F::fit_function_param_limit
+{};
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/identity.hpp b/boost/hof/identity.hpp
new file mode 100644
index 0000000000..0c1f199fb8
--- /dev/null
+++ b/boost/hof/identity.hpp
@@ -0,0 +1,72 @@
+/*=============================================================================
+ Copyright (c) 2012 Paul Fultz II
+ identity.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FUNCTION_IDENTITY_H
+#define BOOST_HOF_GUARD_FUNCTION_IDENTITY_H
+
+/// identity
+/// ========
+///
+/// Description
+/// -----------
+///
+/// The `identity` function is an unary function object that returns whats given to it.
+///
+/// Semantics
+/// ---------
+///
+/// assert(identity(x) == x);
+///
+/// Synopsis
+/// --------
+///
+/// template<class T>
+/// constexpr T identity(T&& x);
+///
+
+#include <utility>
+#include <initializer_list>
+#include <boost/hof/detail/forward.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+
+namespace boost { namespace hof { namespace identity_detail {
+
+struct identity_base
+{
+ template<class T>
+ constexpr T operator()(T&& x) const
+ noexcept(std::is_reference<T>::value || BOOST_HOF_IS_NOTHROW_MOVE_CONSTRUCTIBLE(T))
+ {
+ return BOOST_HOF_FORWARD(T)(x);
+ }
+
+ template<class T>
+ constexpr std::initializer_list<T>& operator()(std::initializer_list<T>& x) const noexcept
+ {
+ return x;
+ }
+
+ template<class T>
+ constexpr const std::initializer_list<T>& operator()(const std::initializer_list<T>& x) const noexcept
+ {
+ return x;
+ }
+
+ template<class T>
+ constexpr std::initializer_list<T> operator()(std::initializer_list<T>&& x) const noexcept(noexcept(std::initializer_list<T>(std::move(x))))
+ {
+ return BOOST_HOF_FORWARD(std::initializer_list<T>)(x);
+ }
+};
+
+}
+
+BOOST_HOF_DECLARE_STATIC_VAR(identity, identity_detail::identity_base);
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/if.hpp b/boost/hof/if.hpp
new file mode 100644
index 0000000000..9eb199f11f
--- /dev/null
+++ b/boost/hof/if.hpp
@@ -0,0 +1,143 @@
+/*=============================================================================
+ Copyright (c) 2015 Paul Fultz II
+ if_.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_IF_H
+#define BOOST_HOF_GUARD_IF_H
+
+/// if
+/// ==
+///
+/// Description
+/// -----------
+///
+/// The `if_` function decorator makes the function callable if the boolean
+/// condition is true. The `if_c` version can be used to give a boolean
+/// condition directly(instead of relying on an integral constant).
+///
+/// When `if_` is false, the function is not callable. It is a subtitution
+/// failure to call the function.
+///
+/// Synopsis
+/// --------
+///
+/// template<class IntegralConstant>
+/// constexpr auto if_(IntegralConstant);
+///
+/// template<bool B, class F>
+/// constexpr auto if_c(F);
+///
+/// Requirements
+/// ------------
+///
+/// IntegralConstant must be:
+///
+/// * IntegralConstant
+///
+/// F must be:
+///
+/// * [ConstInvocable](ConstInvocable)
+/// * MoveConstructible
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+///
+/// struct sum_f
+/// {
+/// template<class T>
+/// int operator()(T x, T y) const
+/// {
+/// return boost::hof::first_of(
+/// boost::hof::if_(std::is_integral<T>())(boost::hof::_ + boost::hof::_),
+/// boost::hof::always(0)
+/// )(x, y);
+/// }
+/// };
+///
+/// int main() {
+/// assert(sum_f()(1, 2) == 3);
+/// assert(sum_f()("", "") == 0);
+/// }
+///
+/// References
+/// ----------
+///
+/// * [static_if](static_if)
+///
+
+#include <boost/hof/always.hpp>
+#include <boost/hof/detail/callable_base.hpp>
+#include <boost/hof/detail/forward.hpp>
+#include <boost/hof/detail/delegate.hpp>
+#include <boost/hof/detail/move.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+
+namespace boost { namespace hof {
+
+namespace detail {
+
+template<class C, class...>
+struct if_depend
+: C
+{};
+
+template<bool Cond, class F>
+struct if_adaptor : detail::callable_base<F>
+{
+ BOOST_HOF_INHERIT_CONSTRUCTOR(if_adaptor, detail::callable_base<F>)
+};
+
+template<class F>
+struct if_adaptor<false, F>
+{
+ template<class... Ts>
+ constexpr if_adaptor(Ts&&...) noexcept
+ {}
+};
+
+template<bool Cond>
+struct make_if_f
+{
+ constexpr make_if_f() noexcept
+ {}
+ template<class F>
+ constexpr if_adaptor<Cond, F> operator()(F f) const BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(F, F&&)
+ {
+ return if_adaptor<Cond, F>(static_cast<F&&>(f));
+ }
+};
+
+struct if_f
+{
+ constexpr if_f()
+ {}
+ template<class Cond, bool B=Cond::type::value>
+ constexpr make_if_f<B> operator()(Cond) const noexcept
+ {
+ return {};
+ }
+};
+
+}
+#if BOOST_HOF_HAS_VARIABLE_TEMPLATES
+template<bool B>
+BOOST_HOF_STATIC_CONSTEXPR detail::make_if_f<B> if_c = {};
+#else
+template<bool B, class F>
+constexpr detail::if_adaptor<B, F> if_c(F f) BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(F, F&&)
+{
+ return detail::if_adaptor<B, F>(static_cast<F&&>(f));
+}
+#endif
+
+BOOST_HOF_DECLARE_STATIC_VAR(if_, detail::if_f);
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/implicit.hpp b/boost/hof/implicit.hpp
new file mode 100644
index 0000000000..f6cbc276ea
--- /dev/null
+++ b/boost/hof/implicit.hpp
@@ -0,0 +1,155 @@
+/*=============================================================================
+ Copyright (c) 2012 Paul Fultz II
+ implicit.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FUNCTION_IMPLICIT_H
+#define BOOST_HOF_GUARD_FUNCTION_IMPLICIT_H
+
+/// implicit
+/// ========
+///
+/// Description
+/// -----------
+///
+/// The `implicit` adaptor is a static function adaptor that uses the type
+/// that the return value can be converted to, in order to determine the type
+/// of the template parameter. In essence, it will deduce the type for the
+/// template parameter using the type of variable the result is assigned to.
+/// Since it is a static function adaptor, the function must be default
+/// constructible.
+///
+/// Synopsis
+/// --------
+///
+/// template<template <class...> class F>
+/// class implicit<F>;
+///
+/// Semantics
+/// ---------
+///
+/// assert(T(implicit<F>()(xs...)) == F<T>()(xs...));
+///
+/// Requirements
+/// ------------
+///
+/// F must be a template class, that is a:
+///
+/// * [ConstFunctionObject](ConstFunctionObject)
+/// * DefaultConstructible
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+/// using namespace boost::hof;
+///
+/// template<class T>
+/// struct auto_caster
+/// {
+/// template<class U>
+/// T operator()(U x)
+/// {
+/// return T(x);
+/// }
+/// };
+///
+/// static constexpr implicit<auto_caster> auto_cast = {};
+///
+/// struct auto_caster_foo
+/// {
+/// int i;
+/// explicit auto_caster_foo(int i_) : i(i_) {}
+///
+/// };
+///
+/// int main() {
+/// float f = 1.5;
+/// int i = auto_cast(f);
+/// auto_caster_foo x = auto_cast(1);
+/// assert(1 == i);
+/// assert(1 == x.i);
+/// }
+///
+
+#include <boost/hof/pack.hpp>
+#include <boost/hof/detail/result_of.hpp>
+
+namespace boost { namespace hof { namespace detail {
+
+template<class F, class Pack, class X, class=void>
+struct is_implicit_callable
+: std::false_type
+{};
+
+#if BOOST_HOF_NO_EXPRESSION_SFINAE
+template<class F, class Pack, class X>
+struct is_implicit_callable<F, Pack, X, typename std::enable_if<
+ std::is_convertible<typename result_of<Pack, id_<F>>::type, X>::value
+>::type>
+: std::true_type
+{};
+#else
+template<class F, class Pack, class X>
+struct is_implicit_callable<F, Pack, X, typename std::enable_if<
+ std::is_convertible<decltype(std::declval<Pack>()(std::declval<F>())), X>::value
+>::type>
+: std::true_type
+{};
+#endif
+
+}
+
+
+template<template <class...> class F>
+struct implicit
+{
+ template<class Pack>
+ struct invoker
+ {
+ Pack p;
+
+ constexpr invoker(Pack pp) BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(Pack, Pack&&)
+ : p(boost::hof::move(pp))
+ {}
+
+ template<class X, class=typename std::enable_if<detail::is_implicit_callable<F<X>, Pack, X>::value>::type>
+ constexpr operator X() const BOOST_HOF_NOEXCEPT(noexcept(p(F<X>())))
+ {
+ return p(F<X>());
+ }
+
+#if !(defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7)
+ invoker (const invoker&) = delete;
+ invoker& operator= (const invoker&) = delete;
+
+ private:
+ friend struct implicit;
+ invoker (invoker&&) = default;
+#endif
+ };
+
+ struct make_invoker
+ {
+ template<class Pack>
+ constexpr invoker<Pack> operator()(Pack p) const BOOST_HOF_NOEXCEPT(noexcept(invoker<Pack>(boost::hof::move(p))))
+ {
+ return invoker<Pack>(boost::hof::move(p));
+ }
+
+ };
+
+ template<class... Ts>
+ constexpr auto operator()(Ts&&... xs) const
+ BOOST_HOF_RETURNS
+ (
+ BOOST_HOF_RETURNS_CONSTRUCT(make_invoker)()(boost::hof::pack_basic(BOOST_HOF_FORWARD(Ts)(xs)...))
+ );
+};
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/indirect.hpp b/boost/hof/indirect.hpp
new file mode 100644
index 0000000000..975f113fb9
--- /dev/null
+++ b/boost/hof/indirect.hpp
@@ -0,0 +1,133 @@
+/*=============================================================================
+ Copyright (c) 2014 Paul Fultz II
+ indirect.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FUNCTION_INDIRECT_H
+#define BOOST_HOF_GUARD_FUNCTION_INDIRECT_H
+
+/// indirect
+/// ========
+///
+/// Description
+/// -----------
+///
+/// The `indirect` function adaptor dereferences the object before calling it.
+///
+/// Synopsis
+/// --------
+///
+/// template<class F>
+/// constexpr indirect_adaptor<F> indirect(F f);
+///
+/// Semantics
+/// ---------
+///
+/// assert(indirect(f)(xs...) == (*f)(xs...));
+///
+/// Requirements
+/// ------------
+///
+/// F must be:
+///
+/// * MoveConstructible
+/// * Dereferenceable
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+/// #include <memory>
+/// using namespace boost::hof;
+///
+/// struct sum
+/// {
+/// template<class T, class U>
+/// T operator()(T x, U y) const
+/// {
+/// return x+y;
+/// }
+/// };
+///
+/// int main() {
+/// int r = indirect(std::make_unique<sum>())(3,2);
+/// assert(r == 5);
+/// }
+///
+
+#include <boost/hof/detail/delegate.hpp>
+#include <boost/hof/detail/result_of.hpp>
+#include <boost/hof/reveal.hpp>
+#include <boost/hof/always.hpp>
+#include <boost/hof/detail/move.hpp>
+#include <boost/hof/detail/make.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+
+namespace boost { namespace hof {
+// TODO: Support non-classes as well
+template<class F>
+struct indirect_adaptor : F
+{
+ typedef indirect_adaptor fit_rewritable1_tag;
+ BOOST_HOF_INHERIT_CONSTRUCTOR(indirect_adaptor, F);
+
+ template<class... Ts>
+ constexpr const F& base_function(Ts&&... xs) const noexcept
+ {
+ return boost::hof::always_ref(*this)(xs...);
+ }
+
+ struct failure
+ : failure_for<decltype(*std::declval<F>())>
+ {};
+
+ BOOST_HOF_RETURNS_CLASS(indirect_adaptor);
+
+ template<class... Ts>
+ constexpr BOOST_HOF_SFINAE_RESULT(decltype(*std::declval<F>()), id_<Ts>...)
+ operator()(Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS
+ (
+ (*BOOST_HOF_MANGLE_CAST(const F&)(BOOST_HOF_CONST_THIS->base_function(xs...)))(BOOST_HOF_FORWARD(Ts)(xs)...)
+ );
+};
+
+template<class F>
+struct indirect_adaptor<F*>
+{
+ typedef indirect_adaptor fit_rewritable1_tag;
+ F* f;
+ constexpr indirect_adaptor() noexcept
+ {}
+
+ constexpr indirect_adaptor(F* x) noexcept
+ : f(x)
+ {}
+
+ template<class... Ts>
+ constexpr F& base_function(Ts&&...) const noexcept
+ {
+ return *f;
+ }
+
+ struct failure
+ : failure_for<F>
+ {};
+
+ BOOST_HOF_RETURNS_CLASS(indirect_adaptor);
+
+ template<class... Ts>
+ constexpr BOOST_HOF_SFINAE_RESULT(F, id_<Ts>...)
+ operator()(Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS
+ (
+ (BOOST_HOF_MANGLE_CAST(F&)(BOOST_HOF_CONST_THIS->base_function(xs...)))(BOOST_HOF_FORWARD(Ts)(xs)...)
+ );
+};
+
+BOOST_HOF_DECLARE_STATIC_VAR(indirect, detail::make<indirect_adaptor>);
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/infix.hpp b/boost/hof/infix.hpp
new file mode 100644
index 0000000000..263297d578
--- /dev/null
+++ b/boost/hof/infix.hpp
@@ -0,0 +1,200 @@
+/*=============================================================================
+ Copyright (c) 2014 Paul Fultz II
+ infix.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FUNCTION_INFIX_H
+#define BOOST_HOF_GUARD_FUNCTION_INFIX_H
+
+/// infix
+/// =====
+///
+/// Description
+/// -----------
+///
+/// The `infix` function adaptor allows the function to be used as an infix
+/// operator. The operator must be placed inside the angle brackets(ie `<`
+/// and `>`).
+///
+/// Synopsis
+/// --------
+///
+/// template<class F>
+/// constexpr infix_adaptor<F> infix(F f);
+///
+/// Semantics
+/// ---------
+///
+/// assert(x <infix(f)> y == f(x, y));
+///
+/// Requirements
+/// ------------
+///
+/// F must be:
+///
+/// * [BinaryInvocable](BinaryInvocable)
+/// * MoveConstructible
+///
+/// Operator precedence
+/// -------------------
+///
+/// Infix operators have the precedence of relational operators. This means
+/// operators such as `+` or `*` have higher precedence:
+///
+/// assert((x + y <infix(f)> z) == ((x + y) <infix(f)> z));
+/// assert((x * y <infix(f)> z) == ((x * y) <infix(f)> z));
+///
+/// However, operators such as `|` or `==` have lower precedence::
+///
+/// assert((x | y <infix(f)> z) == (x | (y <infix(f)> z)));
+/// assert((x == y <infix(f)> z) == (x == (y <infix(f)> z)));
+///
+/// Also, infix operators have left-to-right associativity:
+///
+/// assert(x <infix(f)> y <infix(g)> z == ((x <infix(f)> y) <infix(g)> z));
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+/// using namespace boost::hof;
+///
+/// struct plus_f
+/// {
+/// template<class T, class U>
+/// T operator()(T x, U y) const
+/// {
+/// return x+y;
+/// }
+/// };
+///
+/// int main() {
+/// constexpr infix_adaptor<plus_f> plus = {};
+/// int r = 3 <plus> 2;
+/// assert(r == 5);
+/// }
+///
+
+#include <boost/hof/detail/delegate.hpp>
+#include <boost/hof/detail/callable_base.hpp>
+#include <boost/hof/always.hpp>
+#include <boost/hof/reveal.hpp>
+#include <boost/hof/detail/move.hpp>
+#include <boost/hof/detail/make.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+
+namespace boost { namespace hof {
+
+namespace detail{
+template<class T, class F>
+struct postfix_adaptor : F
+{
+ T x;
+
+ template<class X, class XF>
+ constexpr postfix_adaptor(X&& xp, XF&& fp)
+ BOOST_HOF_NOEXCEPT(BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(F, XF&&) && BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(T, X&&))
+ : F(BOOST_HOF_FORWARD(XF)(fp)), x(BOOST_HOF_FORWARD(X)(xp))
+ {}
+
+ template<class... Ts>
+ constexpr const F& base_function(Ts&&... xs) const noexcept
+ {
+ return boost::hof::always_ref(*this)(xs...);
+ }
+
+ BOOST_HOF_RETURNS_CLASS(postfix_adaptor);
+
+ template<class... Ts>
+ constexpr BOOST_HOF_SFINAE_RESULT(const F&, id_<T&&>, id_<Ts>...)
+ operator()(Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS
+ (
+ (BOOST_HOF_MANGLE_CAST(const F&)(BOOST_HOF_CONST_THIS->base_function(xs...)))(BOOST_HOF_RETURNS_C_CAST(T&&)(BOOST_HOF_CONST_THIS->x), BOOST_HOF_FORWARD(Ts)(xs)...)
+ );
+
+ template<class A>
+ constexpr BOOST_HOF_SFINAE_RESULT(const F&, id_<T&&>, id_<A>)
+ operator>(A&& a) const BOOST_HOF_SFINAE_RETURNS
+ (
+ (BOOST_HOF_MANGLE_CAST(const F&)(BOOST_HOF_CONST_THIS->base_function(a)))(BOOST_HOF_RETURNS_C_CAST(T&&)(BOOST_HOF_CONST_THIS->x), BOOST_HOF_FORWARD(A)(a))
+ );
+};
+
+template<class T, class F>
+constexpr postfix_adaptor<T, F> make_postfix_adaptor(T&& x, F f)
+BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(postfix_adaptor<T, F>, T&&, F&&)
+{
+ return postfix_adaptor<T, F>(BOOST_HOF_FORWARD(T)(x), static_cast<F&&>(f));
+}
+}
+
+template<class F>
+struct infix_adaptor : detail::callable_base<F>
+{
+ typedef infix_adaptor fit_rewritable1_tag;
+ BOOST_HOF_INHERIT_CONSTRUCTOR(infix_adaptor, detail::callable_base<F>);
+
+ template<class... Ts>
+ constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const noexcept
+ {
+ return boost::hof::always_ref(*this)(xs...);
+ }
+
+ template<class... Ts>
+ constexpr const detail::callable_base<F>& infix_base_function(Ts&&... xs) const noexcept
+ {
+ return boost::hof::always_ref(*this)(xs...);
+ }
+
+ BOOST_HOF_RETURNS_CLASS(infix_adaptor);
+
+ template<class... Ts>
+ constexpr auto operator()(Ts&&... xs) const BOOST_HOF_RETURNS
+ (
+ (BOOST_HOF_MANGLE_CAST(const detail::callable_base<F>&)(BOOST_HOF_CONST_THIS->base_function(xs...)))(BOOST_HOF_FORWARD(Ts)(xs)...)
+ );
+};
+
+template<class T, class F>
+constexpr auto operator<(T&& x, const infix_adaptor<F>& i) BOOST_HOF_RETURNS
+(detail::make_postfix_adaptor(BOOST_HOF_FORWARD(T)(x), boost::hof::move(i.base_function(x))));
+
+// TODO: Operators for static_
+
+namespace detail {
+
+template<class F>
+struct static_function_wrapper;
+
+// Operators for static_function_wrapper adaptor
+template<class T, class F>
+auto operator<(T&& x, const boost::hof::detail::static_function_wrapper<F>& f) BOOST_HOF_RETURNS
+(
+ detail::make_postfix_adaptor(BOOST_HOF_FORWARD(T)(x), boost::hof::move(f.base_function().infix_base_function()))
+);
+
+template<class F>
+struct static_default_function;
+
+// Operators for static_default_function adaptor
+template<class T, class F>
+auto operator<(T&& x, const boost::hof::detail::static_default_function<F>&) BOOST_HOF_RETURNS
+(
+ detail::make_postfix_adaptor(BOOST_HOF_FORWARD(T)(x), boost::hof::move(F().infix_base_function()))
+);
+}
+// This overload is needed for gcc
+template<class T, class F>
+constexpr auto operator<(T&& x, const boost::hof::reveal_adaptor<F>& f) BOOST_HOF_RETURNS
+(
+ detail::make_postfix_adaptor(BOOST_HOF_FORWARD(T)(x), f.infix_base_function())
+);
+
+BOOST_HOF_DECLARE_STATIC_VAR(infix, detail::make<infix_adaptor>);
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/is_invocable.hpp b/boost/hof/is_invocable.hpp
new file mode 100644
index 0000000000..edf736e1b2
--- /dev/null
+++ b/boost/hof/is_invocable.hpp
@@ -0,0 +1,72 @@
+/*=============================================================================
+ Copyright (c) 2014 Paul Fultz II
+ is_invocable.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_IS_CALLABLE_H
+#define BOOST_HOF_GUARD_IS_CALLABLE_H
+
+/// is_invocable
+/// ===========
+///
+/// Description
+/// -----------
+///
+/// The `is_invocable` metafunction checks if the function is callable with
+/// certain parameters.
+///
+/// Requirements
+/// ------------
+///
+/// F must be:
+///
+/// * [Invocable](Invocable)
+///
+/// Synopsis
+/// --------
+///
+/// template<class F, class... Ts>
+/// struct is_invocable;
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// using namespace boost::hof;
+///
+/// struct is_invocable_class
+/// {
+/// void operator()(int) const
+/// {
+/// }
+/// };
+/// static_assert(is_invocable<is_invocable_class, int>(), "Not callable");
+///
+/// int main() {}
+///
+
+
+#include <boost/hof/detail/can_be_called.hpp>
+#include <boost/hof/apply.hpp>
+
+namespace boost { namespace hof {
+
+template<class F, class... Ts>
+struct is_invocable
+: detail::can_be_called<detail::apply_f, F, Ts...>
+{};
+
+template<class F, class... Ts, class... Us>
+struct is_invocable<F(Ts...), Us...>
+{
+ static_assert(!std::is_same<F, F>::value,
+ "The is_invocable<F(Args...)> form is not supported because it is problematic."
+ "Please use is_invocable<F, Args...> instead."
+ );
+};
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/is_unpackable.hpp b/boost/hof/is_unpackable.hpp
new file mode 100644
index 0000000000..1f1e0d26cf
--- /dev/null
+++ b/boost/hof/is_unpackable.hpp
@@ -0,0 +1,115 @@
+/*=============================================================================
+ Copyright (c) 2016 Paul Fultz II
+ is_unpackable.hpp
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_IS_UNPACKABLE_HPP
+#define BOOST_HOF_GUARD_IS_UNPACKABLE_HPP
+
+/// is_unpackable
+/// =============
+///
+/// This is a trait that can be used to detect whether the type can be called
+/// with `unpack`.
+///
+/// Synopsis
+/// --------
+///
+/// template<class T>
+/// struct is_unpackable;
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+///
+/// int main() {
+/// static_assert(boost::hof::is_unpackable<std::tuple<int>>::value, "Failed");
+/// }
+///
+
+#include <boost/hof/unpack_sequence.hpp>
+#include <boost/hof/is_invocable.hpp>
+#include <boost/hof/always.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+#include <boost/hof/detail/unpack_tuple.hpp>
+
+namespace boost { namespace hof {
+
+namespace detail {
+
+struct unpack_impl_f
+{
+ template<class F, class Sequence>
+ constexpr auto operator()(F&& f, Sequence&& s) const BOOST_HOF_RETURNS
+ (
+ boost::hof::unpack_sequence<typename std::remove_cv<typename std::remove_reference<Sequence>::type>::type>::
+ apply(BOOST_HOF_FORWARD(F)(f), BOOST_HOF_FORWARD(Sequence)(s))
+ );
+};
+
+BOOST_HOF_DECLARE_STATIC_VAR(unpack_impl, unpack_impl_f);
+
+#if BOOST_HOF_CHECK_UNPACK_SEQUENCE
+struct private_unpack_type {};
+template<class Sequence>
+struct unpack_impl_result
+{
+ static_assert(boost::hof::is_invocable<unpack_impl_f, decltype(boost::hof::always(private_unpack_type())), Sequence>::value,
+ "Unpack is invalid for this sequence. The function used to unpack this sequence is not callable."
+ );
+ typedef decltype(boost::hof::detail::unpack_impl(boost::hof::always(private_unpack_type()), std::declval<Sequence>())) type;
+};
+
+template<class Sequence>
+struct is_proper_sequence
+: std::is_same<
+ private_unpack_type,
+ typename unpack_impl_result<Sequence>::type
+>
+{};
+#endif
+template<class Sequence, class=void>
+struct is_unpackable_impl
+: std::true_type
+{
+#if BOOST_HOF_CHECK_UNPACK_SEQUENCE
+ static_assert(is_proper_sequence<Sequence>::value,
+ "Unpack is invalid for this sequence. The function used to unpack this sequence does not invoke the function."
+ );
+#endif
+};
+
+template<class Sequence>
+struct is_unpackable_impl<Sequence, typename detail::holder<
+ typename unpack_sequence<Sequence>::not_unpackable
+>::type>
+: std::false_type
+{};
+
+}
+
+template<class Sequence>
+struct is_unpackable
+: detail::is_unpackable_impl<
+ typename std::remove_cv<typename std::remove_reference<Sequence>::type>::type
+>
+{
+#if BOOST_HOF_CHECK_UNPACK_SEQUENCE
+typedef detail::is_unpackable_impl<
+ typename std::remove_cv<typename std::remove_reference<Sequence>::type>::type
+> base;
+
+typedef std::conditional<base::value, detail::is_proper_sequence<Sequence>, std::true_type> check;
+static_assert(check::type::value,
+ "Unpack is invalid for this sequence. The function used to unpack this sequence does not invoke the function."
+);
+#endif
+};
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/lambda.hpp b/boost/hof/lambda.hpp
new file mode 100644
index 0000000000..cd3517a623
--- /dev/null
+++ b/boost/hof/lambda.hpp
@@ -0,0 +1,244 @@
+/*=============================================================================
+ Copyright (c) 2014 Paul Fultz II
+ lambda.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FUNCTION_LAMBDA_H
+#define BOOST_HOF_GUARD_FUNCTION_LAMBDA_H
+
+/// BOOST_HOF_STATIC_LAMBDA
+/// =================
+///
+/// Description
+/// -----------
+///
+/// The `BOOST_HOF_STATIC_LAMBDA` macro allows initializing non-capturing lambdas at
+/// compile-time in a `constexpr` expression.
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+///
+/// const constexpr auto add_one = BOOST_HOF_STATIC_LAMBDA(int x)
+/// {
+/// return x + 1;
+/// };
+///
+/// int main() {
+/// assert(3 == add_one(2));
+/// }
+///
+/// BOOST_HOF_STATIC_LAMBDA_FUNCTION
+/// ==========================
+///
+/// Description
+/// -----------
+///
+/// The `BOOST_HOF_STATIC_LAMBDA_FUNCTION` macro allows initializing a global
+/// function object that contains non-capturing lambdas. It also ensures that
+/// the global function object has a unique address across translation units.
+/// This helps prevent possible ODR-violations.
+///
+/// By default, all functions defined with `BOOST_HOF_STATIC_LAMBDA_FUNCTION` use
+/// the `boost::hof::reveal` adaptor to improve error messages.
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+///
+/// BOOST_HOF_STATIC_LAMBDA_FUNCTION(add_one) = [](int x)
+/// {
+/// return x + 1;
+/// };
+/// int main() {
+/// assert(3 == add_one(2));
+/// }
+///
+
+#include <boost/hof/config.hpp>
+
+// TODO: Move this to a detail header
+#if !BOOST_HOF_HAS_CONSTEXPR_LAMBDA || !BOOST_HOF_HAS_INLINE_LAMBDAS
+
+#include <type_traits>
+#include <utility>
+#include <boost/hof/detail/result_of.hpp>
+#include <boost/hof/reveal.hpp>
+#include <boost/hof/detail/constexpr_deduce.hpp>
+#include <boost/hof/function.hpp>
+
+
+#ifndef BOOST_HOF_REWRITE_STATIC_LAMBDA
+#ifdef _MSC_VER
+#define BOOST_HOF_REWRITE_STATIC_LAMBDA 1
+#else
+#define BOOST_HOF_REWRITE_STATIC_LAMBDA 0
+#endif
+#endif
+
+namespace boost { namespace hof {
+
+namespace detail {
+
+template<class F>
+struct static_function_wrapper
+{
+ // Default constructor necessary for MSVC
+ constexpr static_function_wrapper()
+ {}
+
+ static_assert(BOOST_HOF_IS_EMPTY(F), "Function or lambda expression must be empty");
+
+ struct failure
+ : failure_for<F>
+ {};
+
+ template<class... Ts>
+ const F& base_function(Ts&&...) const
+ {
+ return reinterpret_cast<const F&>(*this);
+ }
+
+ BOOST_HOF_RETURNS_CLASS(static_function_wrapper);
+
+ template<class... Ts>
+ BOOST_HOF_SFINAE_RESULT(const F&, id_<Ts>...)
+ operator()(Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS
+ (
+ BOOST_HOF_RETURNS_REINTERPRET_CAST(const F&)(*BOOST_HOF_CONST_THIS)(BOOST_HOF_FORWARD(Ts)(xs)...)
+ );
+};
+
+struct static_function_wrapper_factor
+{
+ constexpr static_function_wrapper_factor()
+ {}
+ template<class F>
+ constexpr static_function_wrapper<F> operator= (const F&) const
+ {
+ // static_assert(std::is_literal_type<static_function_wrapper<F>>::value, "Function wrapper not a literal type");
+ return {};
+ }
+};
+
+#if BOOST_HOF_REWRITE_STATIC_LAMBDA
+template<class T, class=void>
+struct is_rewritable
+: std::false_type
+{};
+
+template<class T>
+struct is_rewritable<T, typename detail::holder<
+ typename T::fit_rewritable_tag
+>::type>
+: std::is_same<typename T::fit_rewritable_tag, T>
+{};
+
+template<class T, class=void>
+struct is_rewritable1
+: std::false_type
+{};
+
+template<class T>
+struct is_rewritable1<T, typename detail::holder<
+ typename T::fit_rewritable1_tag
+>::type>
+: std::is_same<typename T::fit_rewritable1_tag, T>
+{};
+
+
+template<class T, class=void>
+struct rewrite_lambda;
+
+template<template<class...> class Adaptor, class... Ts>
+struct rewrite_lambda<Adaptor<Ts...>, typename std::enable_if<
+ is_rewritable<Adaptor<Ts...>>::value
+>::type>
+{
+ typedef Adaptor<typename rewrite_lambda<Ts>::type...> type;
+};
+
+template<template<class...> class Adaptor, class T, class... Ts>
+struct rewrite_lambda<Adaptor<T, Ts...>, typename std::enable_if<
+ is_rewritable1<Adaptor<T, Ts...>>::value
+>::type>
+{
+ typedef Adaptor<typename rewrite_lambda<T>::type, Ts...> type;
+};
+
+template<class T>
+struct rewrite_lambda<T, typename std::enable_if<
+ std::is_empty<T>::value &&
+ !is_rewritable<T>::value &&
+ !is_rewritable1<T>::value
+>::type>
+{
+ typedef static_function_wrapper<T> type;
+};
+
+template<class T>
+struct rewrite_lambda<T, typename std::enable_if<
+ !std::is_empty<T>::value &&
+ !is_rewritable<T>::value &&
+ !is_rewritable1<T>::value
+>::type>
+{
+ typedef T type;
+};
+
+#endif
+
+template<class T>
+struct reveal_static_lambda_function_wrapper_factor
+{
+ constexpr reveal_static_lambda_function_wrapper_factor()
+ {}
+#if BOOST_HOF_REWRITE_STATIC_LAMBDA
+ template<class F>
+ constexpr reveal_adaptor<typename rewrite_lambda<F>::type>
+ operator=(const F&) const
+ {
+ return reveal_adaptor<typename rewrite_lambda<F>::type>();
+ }
+#elif BOOST_HOF_HAS_CONST_FOLD
+ template<class F>
+ constexpr const reveal_adaptor<F>& operator=(const F&) const
+ {
+ return reinterpret_cast<const reveal_adaptor<F>&>(static_const_var<T>());
+ }
+#else
+ template<class F>
+ constexpr reveal_adaptor<static_function_wrapper<F>> operator=(const F&) const
+ {
+ return {};
+ }
+#endif
+};
+
+}}} // namespace boost::hof
+
+#endif
+
+#if BOOST_HOF_HAS_CONSTEXPR_LAMBDA
+#define BOOST_HOF_STATIC_LAMBDA []
+#else
+#define BOOST_HOF_DETAIL_MAKE_STATIC BOOST_HOF_DETAIL_CONSTEXPR_DEDUCE boost::hof::detail::static_function_wrapper_factor()
+#define BOOST_HOF_STATIC_LAMBDA BOOST_HOF_DETAIL_MAKE_STATIC = []
+#endif
+
+#if BOOST_HOF_HAS_INLINE_LAMBDAS
+#define BOOST_HOF_STATIC_LAMBDA_FUNCTION BOOST_HOF_STATIC_FUNCTION
+#else
+#define BOOST_HOF_DETAIL_MAKE_REVEAL_STATIC(T) BOOST_HOF_DETAIL_CONSTEXPR_DEDUCE_UNIQUE(T) boost::hof::detail::reveal_static_lambda_function_wrapper_factor<T>()
+#define BOOST_HOF_STATIC_LAMBDA_FUNCTION(name) \
+struct fit_private_static_function_ ## name {}; \
+BOOST_HOF_STATIC_AUTO_REF name = BOOST_HOF_DETAIL_MAKE_REVEAL_STATIC(fit_private_static_function_ ## name)
+#endif
+
+#endif
diff --git a/boost/hof/lazy.hpp b/boost/hof/lazy.hpp
new file mode 100644
index 0000000000..713e78a87b
--- /dev/null
+++ b/boost/hof/lazy.hpp
@@ -0,0 +1,299 @@
+/*=============================================================================
+ Copyright (c) 2014 Paul Fultz II
+ lazy.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FUNCTION_LAZY_H
+#define BOOST_HOF_GUARD_FUNCTION_LAZY_H
+
+/// lazy
+/// ====
+///
+/// Description
+/// -----------
+///
+/// The `lazy` function adaptor returns a function object call wrapper for a
+/// function. Calling this wrapper is equivalent to invoking the function. It
+/// is a simple form of lambda expressions, but is constexpr friendly. By
+/// default, `lazy` captures all of its variables by value, just like `bind`.
+/// `std::ref` can be used to capture references instead.
+///
+/// Ultimately, calling `lazy(f)(x)` is the equivalent to calling
+/// `std::bind(f, x)` except the lazy version can be called in a constexpr
+/// context, as well. The `lazy` adaptor is compatible with `std::bind`, so
+/// most of the time `lazy` and `std::bind` can be used interchangeably.
+///
+/// Synopsis
+/// --------
+///
+/// template<class F>
+/// constexpr lazy_adaptor<F> lazy(F f);
+///
+/// Semantics
+/// ---------
+///
+/// assert(lazy(f)(xs...) == std::bind(f, xs...))
+/// assert(lazy(f)(xs...)() == f(xs...))
+/// assert(lazy(f)(_1)(x) == f(x))
+/// assert(lazy(f)(lazy(g)(_1))(x) == f(g(x)))
+///
+/// Requirements
+/// ------------
+///
+/// F must be:
+///
+/// * [ConstInvocable](ConstInvocable)
+/// * MoveConstructible
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+/// using namespace boost::hof;
+///
+/// int main() {
+/// auto add = [](auto x, auto y) { return x+y; };
+/// auto increment = lazy(add)(_1, 1);
+/// assert(increment(5) == 6);
+/// }
+///
+/// References
+/// ----------
+///
+/// * [std::bind](http://en.cppreference.com/w/cpp/utility/functional/bind)
+///
+
+#include <boost/hof/arg.hpp>
+#include <boost/hof/first_of.hpp>
+#include <boost/hof/always.hpp>
+#include <boost/hof/static.hpp>
+#include <boost/hof/detail/delegate.hpp>
+#include <boost/hof/detail/compressed_pair.hpp>
+#include <boost/hof/pack.hpp>
+#include <boost/hof/detail/make.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+#include <functional>
+#include <type_traits>
+
+namespace boost { namespace hof {
+
+namespace detail {
+
+struct placeholder_transformer
+{
+ template<class T, typename std::enable_if<(std::is_placeholder<T>::value > 0), int>::type = 0>
+ constexpr detail::make_args_f<std::size_t, std::is_placeholder<T>::value> operator()(const T&) const noexcept
+ {
+ return {};
+ }
+};
+
+struct bind_transformer
+{
+ template<class T, typename std::enable_if<std::is_bind_expression<T>::value, int>::type = 0>
+ constexpr const T& operator()(const T& x) const noexcept
+ {
+ return x;
+ }
+};
+
+struct ref_transformer
+{
+ template<class T>
+ constexpr auto operator()(std::reference_wrapper<T> x) const
+ BOOST_HOF_SFINAE_RETURNS(boost::hof::always_ref(x.get()));
+};
+
+struct id_transformer
+{
+ template<class T>
+ constexpr auto operator()(T&& x) const
+ BOOST_HOF_SFINAE_RETURNS(always_detail::always_base<T>(BOOST_HOF_FORWARD(T)(x)));
+};
+
+BOOST_HOF_DECLARE_STATIC_VAR(pick_transformer, first_of_adaptor<placeholder_transformer, bind_transformer, ref_transformer, id_transformer>);
+
+template<class T, class Pack>
+constexpr auto lazy_transform(T&& x, const Pack& p) BOOST_HOF_RETURNS
+(
+ p(boost::hof::detail::pick_transformer(BOOST_HOF_FORWARD(T)(x)))
+);
+
+template<class F, class Pack>
+struct lazy_unpack
+{
+ const F& f;
+ const Pack& p;
+
+ constexpr lazy_unpack(const F& fp, const Pack& pp) noexcept
+ : f(fp), p(pp)
+ {}
+
+ template<class... Ts>
+ constexpr auto operator()(Ts&&... xs) const BOOST_HOF_RETURNS
+ (
+ f(lazy_transform(BOOST_HOF_FORWARD(Ts)(xs), p)...)
+ );
+};
+
+template<class F, class Pack>
+constexpr lazy_unpack<F, Pack> make_lazy_unpack(const F& f, const Pack& p) noexcept
+{
+ return lazy_unpack<F, Pack>(f, p);
+}
+
+template<class F, class Pack>
+struct lazy_invoker
+: detail::compressed_pair<F, Pack>
+{
+ typedef detail::compressed_pair<F, Pack> base_type;
+ typedef lazy_invoker fit_rewritable1_tag;
+
+#ifdef _MSC_VER
+ BOOST_HOF_INHERIT_CONSTRUCTOR(lazy_invoker, base_type)
+#else
+ BOOST_HOF_INHERIT_DEFAULT_EMPTY(lazy_invoker, base_type)
+
+ template<class X, class Y,
+ BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(base_type, X&&, Y&&)
+ >
+ constexpr lazy_invoker(X&& x, Y&& y)
+ BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(base_type, X&&, Y&&)
+ : base_type(BOOST_HOF_FORWARD(X)(x), BOOST_HOF_FORWARD(Y)(y))
+ {}
+#endif
+
+ template<class... Ts>
+ constexpr const F& base_function(Ts&&... xs) const noexcept
+ {
+ return this->first(xs...);
+ }
+
+ template<class... Ts>
+ constexpr const Pack& get_pack(Ts&&... xs) const noexcept
+ {
+ return this->second(xs...);
+ }
+
+ BOOST_HOF_RETURNS_CLASS(lazy_invoker);
+
+ template<class... Ts>
+ constexpr auto operator()(Ts&&... xs) const BOOST_HOF_RETURNS
+ (
+ BOOST_HOF_MANGLE_CAST(const Pack&)(BOOST_HOF_CONST_THIS->get_pack(xs...))(
+ boost::hof::detail::make_lazy_unpack(
+ BOOST_HOF_MANGLE_CAST(const F&)(BOOST_HOF_CONST_THIS->base_function(xs...)),
+ boost::hof::pack_forward(BOOST_HOF_FORWARD(Ts)(xs)...)
+ )
+ )
+ );
+};
+
+template<class F, class Pack>
+constexpr lazy_invoker<F, Pack> make_lazy_invoker(F f, Pack pack)
+BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(lazy_invoker<F, Pack>, F&&, Pack&&)
+{
+ return lazy_invoker<F, Pack>(static_cast<F&&>(f), static_cast<Pack&&>(pack));
+}
+
+template<class F>
+struct lazy_nullary_invoker : F
+{
+ BOOST_HOF_INHERIT_CONSTRUCTOR(lazy_nullary_invoker, F);
+
+ template<class... Ts>
+ constexpr const F& base_function(Ts&&... xs) const noexcept
+ {
+ return boost::hof::always_ref(*this)(xs...);
+ }
+
+ BOOST_HOF_RETURNS_CLASS(lazy_nullary_invoker);
+
+ template<class... Ts>
+ constexpr auto operator()(Ts&&... xs) const BOOST_HOF_RETURNS
+ (
+ BOOST_HOF_MANGLE_CAST(const F&)(BOOST_HOF_CONST_THIS->base_function(xs...))()
+ );
+};
+
+template<class F>
+constexpr lazy_nullary_invoker<F> make_lazy_nullary_invoker(F f)
+BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(lazy_nullary_invoker<F>, F&&)
+{
+ return lazy_nullary_invoker<F>(static_cast<F&&>(f));
+}
+}
+
+
+template<class F>
+struct lazy_adaptor : detail::callable_base<F>
+{
+ BOOST_HOF_INHERIT_CONSTRUCTOR(lazy_adaptor, detail::callable_base<F>);
+
+ template<class... Ts>
+ constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const noexcept
+ {
+ return boost::hof::always_ref(*this)(xs...);
+ }
+
+ BOOST_HOF_RETURNS_CLASS(lazy_adaptor);
+
+ template<class T, class... Ts>
+ constexpr auto operator()(T x, Ts... xs) const BOOST_HOF_RETURNS
+ (
+ boost::hof::detail::make_lazy_invoker(BOOST_HOF_RETURNS_C_CAST(detail::callable_base<F>&&)(BOOST_HOF_CONST_THIS->base_function(x, xs...)),
+ boost::hof::pack_basic(BOOST_HOF_RETURNS_STATIC_CAST(T&&)(x), BOOST_HOF_RETURNS_STATIC_CAST(Ts&&)(xs)...))
+ );
+
+ // Workaround for gcc 4.7
+ template<class Unused=int>
+ constexpr detail::lazy_nullary_invoker<F> operator()() const
+ BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(
+ boost::hof::detail::make_lazy_nullary_invoker(BOOST_HOF_RETURNS_C_CAST(detail::callable_base<F>&&)(
+ BOOST_HOF_CONST_THIS->base_function(BOOST_HOF_RETURNS_CONSTRUCT(Unused)())
+ ))
+ )
+ {
+ return boost::hof::detail::make_lazy_nullary_invoker((detail::callable_base<F>&&)(
+ this->base_function(Unused())
+ ));
+ }
+
+ // TODO: Overloads to use with ref qualifiers
+
+ // template<class... Ts>
+ // constexpr auto operator()(Ts... xs) const& BOOST_HOF_RETURNS
+ // (
+ // boost::hof::detail::make_lazy_invoker(this->base_function(xs...),
+ // pack(boost::hof::move(xs)...))
+ // );
+
+ // template<class... Ts>
+ // constexpr auto operator()(Ts... xs) && BOOST_HOF_RETURNS
+ // (
+ // boost::hof::detail::make_lazy_invoker((F&&)this->base_function(xs...),
+ // pack(boost::hof::move(xs)...))
+ // );
+
+};
+
+BOOST_HOF_DECLARE_STATIC_VAR(lazy, detail::make<lazy_adaptor>);
+
+}} // namespace boost::hof
+
+namespace std {
+ template<class F, class Pack>
+ struct is_bind_expression<boost::hof::detail::lazy_invoker<F, Pack>>
+ : std::true_type
+ {};
+
+ template<class F>
+ struct is_bind_expression<boost::hof::detail::lazy_nullary_invoker<F>>
+ : std::true_type
+ {};
+}
+
+#endif
diff --git a/boost/hof/lift.hpp b/boost/hof/lift.hpp
new file mode 100644
index 0000000000..0fe6652db7
--- /dev/null
+++ b/boost/hof/lift.hpp
@@ -0,0 +1,110 @@
+/*=============================================================================
+ Copyright (c) 2015 Paul Fultz II
+ lift.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FUNCTION_LIFT_H
+#define BOOST_HOF_GUARD_FUNCTION_LIFT_H
+
+/// BOOST_HOF_LIFT
+/// ========
+///
+/// Description
+/// -----------
+///
+/// The macros `BOOST_HOF_LIFT` and `BOOST_HOF_LIFT_CLASS` provide a lift operator that
+/// will wrap a template function in a function object so it can be passed to
+/// higher-order functions. The `BOOST_HOF_LIFT` macro will wrap the function using
+/// a generic lambda. As such, it will not preserve `constexpr`. The
+/// `BOOST_HOF_LIFT_CLASS` can be used to declare a class that will wrap function.
+/// This will preserve `constexpr` and it can be used on older compilers that
+/// don't support generic lambdas yet.
+///
+/// Limitation
+/// ----------
+///
+/// In C++14, `BOOST_HOF_LIFT` doesn't support `constexpr` due to using a generic
+/// lambda. Instead, `BOOST_HOF_LIFT_CLASS` can be used. In C++17, there is no such
+/// limitation.
+///
+/// Synopsis
+/// --------
+///
+/// // Wrap the function in a generic lambda
+/// #define BOOST_HOF_LIFT(...)
+///
+/// // Declare a class named `name` that will forward to the function
+/// #define BOOST_HOF_LIFT_CLASS(name, ...)
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+/// #include <algorithm>
+///
+/// // Declare the class `max_f`
+/// BOOST_HOF_LIFT_CLASS(max_f, std::max);
+///
+/// int main() {
+/// auto my_max = BOOST_HOF_LIFT(std::max);
+/// assert(my_max(3, 4) == std::max(3, 4));
+/// assert(max_f()(3, 4) == std::max(3, 4));
+/// }
+///
+
+#include <boost/hof/detail/delegate.hpp>
+#include <boost/hof/returns.hpp>
+#include <boost/hof/lambda.hpp>
+#include <boost/hof/detail/forward.hpp>
+
+namespace boost { namespace hof { namespace detail {
+
+template<class F, class NoExcept>
+struct lift_noexcept : F
+{
+ BOOST_HOF_INHERIT_CONSTRUCTOR(lift_noexcept, F);
+
+ template<class... Ts>
+ constexpr auto operator()(Ts&&... xs) const
+ noexcept(decltype(std::declval<NoExcept>()(BOOST_HOF_FORWARD(Ts)(xs)...)){})
+ -> decltype(std::declval<F>()(BOOST_HOF_FORWARD(Ts)(xs)...))
+ { return F(*this)(BOOST_HOF_FORWARD(Ts)(xs)...);}
+};
+
+template<class F, class NoExcept>
+constexpr lift_noexcept<F, NoExcept> make_lift_noexcept(F f, NoExcept)
+{
+ return {f};
+}
+
+}
+
+}} // namespace boost::hof
+
+#define BOOST_HOF_LIFT_IS_NOEXCEPT(...) std::integral_constant<bool, noexcept(decltype(__VA_ARGS__)(__VA_ARGS__))>{}
+
+#if defined (_MSC_VER)
+#define BOOST_HOF_LIFT(...) (BOOST_HOF_STATIC_LAMBDA { BOOST_HOF_LIFT_CLASS(fit_local_lift_t, __VA_ARGS__); return fit_local_lift_t(); }())
+#elif defined (__clang__)
+#define BOOST_HOF_LIFT(...) (boost::hof::detail::make_lift_noexcept( \
+ BOOST_HOF_STATIC_LAMBDA(auto&&... xs) \
+ -> decltype((__VA_ARGS__)(BOOST_HOF_FORWARD(decltype(xs))(xs)...)) \
+ { return (__VA_ARGS__)(BOOST_HOF_FORWARD(decltype(xs))(xs)...); }, \
+ BOOST_HOF_STATIC_LAMBDA(auto&&... xs) { return BOOST_HOF_LIFT_IS_NOEXCEPT((__VA_ARGS__)(BOOST_HOF_FORWARD(decltype(xs))(xs)...)); } \
+))
+#else
+#define BOOST_HOF_LIFT(...) (BOOST_HOF_STATIC_LAMBDA(auto&&... xs) BOOST_HOF_RETURNS((__VA_ARGS__)(BOOST_HOF_FORWARD(decltype(xs))(xs)...)))
+#endif
+
+#define BOOST_HOF_LIFT_CLASS(name, ...) \
+struct name \
+{ \
+ template<class... Ts> \
+ constexpr auto operator()(Ts&&... xs) const \
+ BOOST_HOF_RETURNS((__VA_ARGS__)(BOOST_HOF_FORWARD(Ts)(xs)...)) \
+}
+
+#endif
diff --git a/boost/hof/limit.hpp b/boost/hof/limit.hpp
new file mode 100644
index 0000000000..e80356386c
--- /dev/null
+++ b/boost/hof/limit.hpp
@@ -0,0 +1,142 @@
+/*=============================================================================
+ Copyright (c) 2016 Paul Fultz II
+ limit.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_LIMIT_H
+#define BOOST_HOF_GUARD_LIMIT_H
+
+/// limit
+/// =====
+///
+/// Description
+/// -----------
+///
+/// The `limit` function decorator annotates the function with the max number
+/// of parameters. The `limit_c` version can be used to give the max number
+/// directly(instead of relying on an integral constant). The parameter limit
+/// can be read by using the [`function_param_limit`](function_param_limit)
+/// trait. Using `limit` is useful to improve error reporting with partially
+/// evaluated functions.
+///
+/// Synopsis
+/// --------
+///
+/// template<class IntegralConstant>
+/// constexpr auto limit(IntegralConstant);
+///
+/// template<std::size_t N, class F>
+/// constexpr auto limit_c(F);
+///
+/// Requirements
+/// ------------
+///
+/// IntegralConstant must be:
+///
+/// * IntegralConstant
+///
+/// F must be:
+///
+/// * [ConstInvocable](ConstInvocable)
+/// * MoveConstructible
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+/// using namespace boost::hof;
+///
+/// struct sum_f
+/// {
+/// template<class T>
+/// int operator()(T x, T y) const
+/// {
+/// return x+y;
+/// }
+/// };
+/// BOOST_HOF_STATIC_FUNCTION(sum) = limit_c<2>(sum_f());
+///
+/// int main() {
+/// assert(3 == sum(1, 2));
+/// }
+///
+/// See Also
+/// --------
+///
+/// * [Partial function evaluation](<Partial function evaluation>)
+/// * [function_param_limit](function_param_limit)
+///
+
+#include <boost/hof/detail/callable_base.hpp>
+#include <boost/hof/detail/forward.hpp>
+#include <boost/hof/detail/delegate.hpp>
+#include <boost/hof/detail/move.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+#include <boost/hof/always.hpp>
+#include <boost/hof/function_param_limit.hpp>
+
+namespace boost { namespace hof {
+
+namespace detail {
+// TODO: Make this work with fit_rewritable1_tag
+template<std::size_t N, class F>
+struct limit_adaptor : detail::callable_base<F>
+{
+ typedef std::integral_constant<std::size_t, N> fit_function_param_limit;
+ BOOST_HOF_INHERIT_CONSTRUCTOR(limit_adaptor, detail::callable_base<F>)
+
+ template<class... Ts>
+ constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const
+ {
+ return boost::hof::always_ref(*this)(xs...);
+ }
+
+ BOOST_HOF_RETURNS_CLASS(limit_adaptor);
+
+ template<class... Ts, class=typename std::enable_if<(sizeof...(Ts) <= N)>::type>
+ constexpr BOOST_HOF_SFINAE_RESULT(const detail::callable_base<F>&, id_<Ts>...)
+ operator()(Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS
+ (
+ (BOOST_HOF_MANGLE_CAST(const detail::callable_base<F>&)(BOOST_HOF_CONST_THIS->base_function(xs...)))
+ (BOOST_HOF_FORWARD(Ts)(xs)...)
+ );
+
+};
+
+template<std::size_t N>
+struct make_limit_f
+{
+ constexpr make_limit_f()
+ {}
+ template<class F>
+ constexpr limit_adaptor<N, F> operator()(F f) const
+ {
+ return limit_adaptor<N, F>(static_cast<F&&>(f));
+ }
+};
+
+struct limit_f
+{
+ template<class IntegralConstant, std::size_t N=IntegralConstant::type::value>
+ constexpr make_limit_f<N> operator()(IntegralConstant) const
+ {
+ return {};
+ }
+};
+
+}
+
+template<std::size_t N, class F>
+constexpr detail::limit_adaptor<N, F> limit_c(F f)
+{
+ return detail::limit_adaptor<N, F>(static_cast<F&&>(f));
+}
+
+BOOST_HOF_DECLARE_STATIC_VAR(limit, detail::limit_f);
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/match.hpp b/boost/hof/match.hpp
new file mode 100644
index 0000000000..abf60194f5
--- /dev/null
+++ b/boost/hof/match.hpp
@@ -0,0 +1,121 @@
+/*=============================================================================
+ Copyright (c) 2012 Paul Fultz II
+ match.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FUNCTION_OVERLOAD_H
+#define BOOST_HOF_GUARD_FUNCTION_OVERLOAD_H
+
+/// match
+/// =====
+///
+/// Description
+/// -----------
+///
+/// The `match` function adaptor combines several functions together and
+/// resolves which one should be called by using C++ overload resolution. This
+/// is different than the [`first_of`](/include/boost/hof/conditional) adaptor which resolves
+/// them based on order.
+///
+/// Synopsis
+/// --------
+///
+/// template<class... Fs>
+/// constexpr match_adaptor<Fs...> match(Fs...fs);
+///
+/// Requirements
+/// ------------
+///
+/// Fs must be:
+///
+/// * [ConstInvocable](ConstInvocable)
+/// * MoveConstructible
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// using namespace boost::hof;
+///
+/// struct int_class
+/// {
+/// int operator()(int) const
+/// {
+/// return 1;
+/// }
+/// };
+///
+/// struct foo
+/// {};
+///
+/// struct foo_class
+/// {
+/// foo operator()(foo) const
+/// {
+/// return foo();
+/// }
+/// };
+///
+/// typedef match_adaptor<int_class, foo_class> fun;
+///
+/// static_assert(std::is_same<int, decltype(fun()(1))>::value, "Failed match");
+/// static_assert(std::is_same<foo, decltype(fun()(foo()))>::value, "Failed match");
+///
+/// int main() {}
+///
+/// References
+/// ----------
+///
+/// * [POO51](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0051r2.pdf) - Proposal for C++
+/// Proposal for C++ generic overload function
+///
+
+#include <boost/hof/reveal.hpp>
+#include <boost/hof/detail/callable_base.hpp>
+#include <boost/hof/detail/delegate.hpp>
+#include <boost/hof/detail/move.hpp>
+#include <boost/hof/detail/make.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+
+namespace boost { namespace hof {
+
+template<class...Fs> struct match_adaptor;
+
+template<class F, class...Fs>
+struct match_adaptor<F, Fs...> : detail::callable_base<F>, match_adaptor<Fs...>
+{
+ typedef match_adaptor<Fs...> base;
+ typedef match_adaptor fit_rewritable_tag;
+
+ struct failure
+ : failure_for<detail::callable_base<F>, Fs...>
+ {};
+
+ BOOST_HOF_INHERIT_DEFAULT(match_adaptor, detail::callable_base<F>, base);
+
+ template<class X, class... Xs, BOOST_HOF_ENABLE_IF_CONVERTIBLE(X, detail::callable_base<F>), BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(base, Xs...)>
+ constexpr match_adaptor(X&& f1, Xs&& ... fs)
+ : detail::callable_base<F>(BOOST_HOF_FORWARD(X)(f1)), base(BOOST_HOF_FORWARD(Xs)(fs)...)
+ {}
+
+ using F::operator();
+ using base::operator();
+};
+
+template<class F>
+struct match_adaptor<F> : detail::callable_base<F>
+{
+ typedef detail::callable_base<F> base;
+ typedef match_adaptor fit_rewritable_tag;
+ using F::operator();
+
+ BOOST_HOF_INHERIT_CONSTRUCTOR(match_adaptor, detail::callable_base<F>);
+};
+
+BOOST_HOF_DECLARE_STATIC_VAR(match, detail::make<match_adaptor>);
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/mutable.hpp b/boost/hof/mutable.hpp
new file mode 100644
index 0000000000..b704c027cf
--- /dev/null
+++ b/boost/hof/mutable.hpp
@@ -0,0 +1,68 @@
+/*=============================================================================
+ Copyright (c) 2014 Paul Fultz II
+ mutable.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FUNCTION_MUTABLE_H
+#define BOOST_HOF_GUARD_FUNCTION_MUTABLE_H
+
+/// mutable
+/// =======
+///
+/// Description
+/// -----------
+///
+/// The `mutable` function adaptor allows using a non-const function object
+/// inside of a const-function object. In Fit, all the function adaptors use
+/// `const` call overloads, so if there is a function that has a non-const
+/// call operator, it couldn't be used directly. So, `mutable_` allows the
+/// function to be used inside of the call operator.
+///
+/// NOTE: This function should be used with caution since many functions are
+/// copied, so relying on some internal shared state can be error-prone.
+///
+/// Synopsis
+/// --------
+///
+/// template<class F>
+/// mutable_adaptor<F> mutable_(F f)
+///
+/// Requirements
+/// ------------
+///
+/// F must be:
+///
+/// * [MutableFunctionObject](MutableFunctionObject)
+/// * MoveConstructible
+///
+
+#include <boost/hof/detail/result_of.hpp>
+#include <boost/hof/detail/delegate.hpp>
+#include <boost/hof/detail/move.hpp>
+#include <boost/hof/detail/make.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+
+namespace boost { namespace hof {
+
+template<class F>
+struct mutable_adaptor
+{
+ mutable F f;
+
+ BOOST_HOF_DELEGATE_CONSTRUCTOR(mutable_adaptor, F, f);
+
+ BOOST_HOF_RETURNS_CLASS(mutable_adaptor);
+
+ template<class... Ts>
+ BOOST_HOF_SFINAE_RESULT(F, id_<Ts>...)
+ operator()(Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS(BOOST_HOF_CONST_THIS->f(BOOST_HOF_FORWARD(Ts)(xs)...));
+};
+
+BOOST_HOF_DECLARE_STATIC_VAR(mutable_, detail::make<mutable_adaptor>);
+
+}} // namespace boost::hof
+
+
+#endif
diff --git a/boost/hof/pack.hpp b/boost/hof/pack.hpp
new file mode 100644
index 0000000000..b0c5b2c206
--- /dev/null
+++ b/boost/hof/pack.hpp
@@ -0,0 +1,423 @@
+/*=============================================================================
+ Copyright (c) 2014 Paul Fultz II
+ pack.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FUNCTION_PACK_H
+#define BOOST_HOF_GUARD_FUNCTION_PACK_H
+
+/// pack
+/// ====
+///
+/// Description
+/// -----------
+///
+/// The `pack` function returns a higher order function object that takes a
+/// function that will be passed the initial elements. The function object is
+/// a sequence that can be unpacked with `unpack_adaptor` as well. Also,
+/// `pack_join` can be used to join multiple packs together.
+///
+/// Synopsis
+/// --------
+///
+/// // Decay everything before capturing
+/// template<class... Ts>
+/// constexpr auto pack(Ts&&... xs);
+///
+/// // Capture lvalues by reference and rvalue reference by reference
+/// template<class... Ts>
+/// constexpr auto pack_forward(Ts&&... xs);
+///
+/// // Capture lvalues by reference and rvalues by value.
+/// template<class... Ts>
+/// constexpr auto pack_basic(Ts&&... xs);
+///
+/// // Join multiple packs together
+/// template<class... Ts>
+/// constexpr auto pack_join(Ts&&... xs);
+///
+/// Semantics
+/// ---------
+///
+/// assert(pack(xs...)(f) == f(xs...));
+/// assert(unpack(f)(pack(xs...)) == f(xs...));
+///
+/// assert(pack_join(pack(xs...), pack(ys...)) == pack(xs..., ys...));
+///
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+/// using namespace boost::hof;
+///
+/// struct sum
+/// {
+/// template<class T, class U>
+/// T operator()(T x, U y) const
+/// {
+/// return x+y;
+/// }
+/// };
+///
+/// int main() {
+/// int r = pack(3, 2)(sum());
+/// assert(r == 5);
+/// }
+///
+/// See Also
+/// --------
+///
+/// * [unpack](unpack)
+///
+
+#include <boost/hof/detail/seq.hpp>
+#include <boost/hof/detail/delegate.hpp>
+#include <boost/hof/detail/remove_rvalue_reference.hpp>
+#include <boost/hof/detail/unwrap.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+#include <boost/hof/unpack_sequence.hpp>
+#include <boost/hof/returns.hpp>
+#include <boost/hof/alias.hpp>
+#include <boost/hof/decay.hpp>
+
+namespace boost { namespace hof { namespace detail {
+
+template<class...>
+struct pack_tag
+{};
+
+template<class T, class Tag>
+struct pack_holder
+: detail::alias_empty<T, Tag>
+{};
+
+template<class Seq, class... Ts>
+struct pack_base;
+
+template<class T>
+struct is_copyable
+: std::integral_constant<bool, (
+ BOOST_HOF_IS_CONSTRUCTIBLE(T, const T&)
+)>
+{};
+
+template<class T>
+struct is_copyable<T&>
+: std::true_type
+{};
+
+template<class T>
+struct is_copyable<T&&>
+: std::true_type
+{};
+
+template<class T, class Tag, class X, class... Ts, typename std::enable_if<
+ is_copyable<T>::value && !std::is_lvalue_reference<T>::value
+, int>::type = 0>
+constexpr T pack_get(X&& x, Ts&&... xs) noexcept(BOOST_HOF_IS_NOTHROW_COPY_CONSTRUCTIBLE(T))
+{
+ return static_cast<T>(boost::hof::alias_value<Tag, T>(BOOST_HOF_FORWARD(X)(x), xs...));
+}
+
+template<class T, class Tag, class X, class... Ts, typename std::enable_if<
+ std::is_lvalue_reference<T>::value
+, int>::type = 0>
+constexpr T pack_get(X&& x, Ts&&... xs) noexcept
+{
+ return boost::hof::alias_value<Tag, T>(x, xs...);
+}
+
+template<class T, class Tag, class X, class... Ts, typename std::enable_if<
+ !is_copyable<T>::value
+, int>::type = 0>
+constexpr auto pack_get(X&& x, Ts&&... xs) BOOST_HOF_RETURNS
+(
+ boost::hof::alias_value<Tag, T>(BOOST_HOF_FORWARD(X)(x), xs...)
+);
+
+#if (defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7) || defined(_MSC_VER)
+template<class... Ts>
+struct pack_holder_base
+: Ts::type...
+{
+ template<class... Xs, class=typename std::enable_if<(sizeof...(Xs) == sizeof...(Ts))>::type>
+ constexpr pack_holder_base(Xs&&... xs)
+ BOOST_HOF_NOEXCEPT(BOOST_HOF_AND_UNPACK(BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(typename Ts::type, Xs&&)))
+ : Ts::type(BOOST_HOF_FORWARD(Xs)(xs))...
+ {}
+#ifndef _MSC_VER
+ // BOOST_HOF_INHERIT_DEFAULT(pack_holder_base, typename std::remove_cv<typename std::remove_reference<typename Ts::type>::type>::type...)
+ BOOST_HOF_INHERIT_DEFAULT(pack_holder_base, typename Ts::type...)
+#endif
+};
+
+template<class T>
+struct pack_holder_base<T>
+: T::type
+{
+ typedef typename T::type base;
+ BOOST_HOF_INHERIT_CONSTRUCTOR(pack_holder_base, base);
+};
+
+template<class... Ts>
+struct pack_holder_builder
+{
+ template<class T, std::size_t N>
+ struct apply
+ : pack_holder<T, pack_tag<seq<N>, Ts...>>
+ {};
+};
+
+template<std::size_t... Ns, class... Ts>
+struct pack_base<seq<Ns...>, Ts...>
+: pack_holder_base<typename pack_holder_builder<Ts...>::template apply<Ts, Ns>...>
+{
+ typedef pack_holder_base<typename pack_holder_builder<Ts...>::template apply<Ts, Ns>...> base;
+ template<class X1, class X2, class... Xs>
+ constexpr pack_base(X1&& x1, X2&& x2, Xs&&... xs)
+ BOOST_HOF_NOEXCEPT(BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(base, X1&&, X2&&, Xs&...))
+ : base(BOOST_HOF_FORWARD(X1)(x1), BOOST_HOF_FORWARD(X2)(x2), BOOST_HOF_FORWARD(Xs)(xs)...)
+ {}
+
+ template<class X1, typename std::enable_if<(BOOST_HOF_IS_CONSTRUCTIBLE(base, X1)), int>::type = 0>
+ constexpr pack_base(X1&& x1)
+ BOOST_HOF_NOEXCEPT(BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(base, X1&&))
+ : base(BOOST_HOF_FORWARD(X1)(x1))
+ {}
+
+ // BOOST_HOF_INHERIT_DEFAULT(pack_base, typename std::remove_cv<typename std::remove_reference<Ts>::type>::type...);
+ BOOST_HOF_INHERIT_DEFAULT(pack_base, Ts...);
+
+ BOOST_HOF_RETURNS_CLASS(pack_base);
+
+ template<class F>
+ constexpr auto operator()(F&& f) const BOOST_HOF_RETURNS
+ (
+ f(boost::hof::detail::pack_get<Ts, pack_tag<seq<Ns>, Ts...>>(*BOOST_HOF_CONST_THIS, f)...)
+ );
+
+ typedef std::integral_constant<std::size_t, sizeof...(Ts)> fit_function_param_limit;
+
+ template<class F>
+ struct apply
+ : F::template apply<Ts...>
+ {};
+};
+
+template<class T>
+struct pack_base<seq<0>, T>
+: pack_holder_base<pack_holder<T, pack_tag<seq<0>, T>>>
+{
+ typedef pack_holder_base<pack_holder<T, pack_tag<seq<0>, T>>> base;
+
+ template<class X1, typename std::enable_if<(BOOST_HOF_IS_CONSTRUCTIBLE(base, X1)), int>::type = 0>
+ constexpr pack_base(X1&& x1)
+ BOOST_HOF_NOEXCEPT(BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(base, X1&&))
+ : base(BOOST_HOF_FORWARD(X1)(x1))
+ {}
+
+ BOOST_HOF_INHERIT_DEFAULT(pack_base, T);
+
+ BOOST_HOF_RETURNS_CLASS(pack_base);
+
+ template<class F>
+ constexpr auto operator()(F&& f) const BOOST_HOF_RETURNS
+ (
+ f(boost::hof::detail::pack_get<T, pack_tag<seq<0>, T>>(*BOOST_HOF_CONST_THIS, f))
+ );
+
+ typedef std::integral_constant<std::size_t, 1> fit_function_param_limit;
+
+ template<class F>
+ struct apply
+ : F::template apply<T>
+ {};
+};
+
+#else
+
+template<std::size_t... Ns, class... Ts>
+struct pack_base<seq<Ns...>, Ts...>
+: pack_holder<Ts, pack_tag<seq<Ns>, Ts...>>::type...
+{
+ // BOOST_HOF_INHERIT_DEFAULT(pack_base, typename std::remove_cv<typename std::remove_reference<Ts>::type>::type...);
+ BOOST_HOF_INHERIT_DEFAULT(pack_base, Ts...);
+
+ template<class... Xs, BOOST_HOF_ENABLE_IF_CONVERTIBLE_UNPACK(Xs&&, typename pack_holder<Ts, pack_tag<seq<Ns>, Ts...>>::type)>
+ constexpr pack_base(Xs&&... xs)
+ BOOST_HOF_NOEXCEPT(BOOST_HOF_AND_UNPACK(BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(typename pack_holder<Ts, pack_tag<seq<Ns>, Ts...>>::type, Xs&&)))
+ : pack_holder<Ts, pack_tag<seq<Ns>, Ts...>>::type(BOOST_HOF_FORWARD(Xs)(xs))...
+ {}
+
+ // typedef pack_base<seq<Ns...>, Ts...> self_t;
+
+ BOOST_HOF_RETURNS_CLASS(pack_base);
+
+ template<class F>
+ constexpr auto operator()(F&& f) const BOOST_HOF_RETURNS
+ (
+ f(boost::hof::detail::pack_get<Ts, pack_tag<seq<Ns>, Ts...>>(*BOOST_HOF_CONST_THIS, f)...)
+ );
+
+ typedef std::integral_constant<std::size_t, sizeof...(Ts)> fit_function_param_limit;
+
+ template<class F>
+ struct apply
+ : F::template apply<Ts...>
+ {};
+};
+
+#endif
+
+template<>
+struct pack_base<seq<> >
+{
+ template<class F>
+ constexpr auto operator()(F&& f) const BOOST_HOF_RETURNS
+ (f());
+
+ typedef std::integral_constant<std::size_t, 0> fit_function_param_limit;
+
+ template<class F>
+ struct apply
+ : F::template apply<>
+ {};
+};
+
+#define BOOST_HOF_DETAIL_UNPACK_PACK_BASE(ref, move) \
+template<class F, std::size_t... Ns, class... Ts> \
+constexpr auto unpack_pack_base(F&& f, pack_base<seq<Ns...>, Ts...> ref x) \
+BOOST_HOF_RETURNS(f(boost::hof::alias_value<pack_tag<seq<Ns>, Ts...>, Ts>(move(x), f)...))
+BOOST_HOF_UNARY_PERFECT_FOREACH(BOOST_HOF_DETAIL_UNPACK_PACK_BASE)
+
+template<class P1, class P2>
+struct pack_join_base;
+
+// TODO: Extend to join more than two packs at a time
+template<std::size_t... Ns1, class... Ts1, std::size_t... Ns2, class... Ts2>
+struct pack_join_base<pack_base<seq<Ns1...>, Ts1...>, pack_base<seq<Ns2...>, Ts2...>>
+{
+ static constexpr long total_size = sizeof...(Ts1) + sizeof...(Ts2);
+ typedef pack_base<typename detail::gens<total_size>::type, Ts1..., Ts2...> result_type;
+
+ template<class P1, class P2>
+ static constexpr result_type call(P1&& p1, P2&& p2)
+ BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(
+ result_type(
+ boost::hof::detail::pack_get<Ts1, pack_tag<seq<Ns1>, Ts1...>>(BOOST_HOF_FORWARD(P1)(p1))...,
+ boost::hof::detail::pack_get<Ts2, pack_tag<seq<Ns2>, Ts2...>>(BOOST_HOF_FORWARD(P2)(p2))...)
+ )
+ {
+ return result_type(
+ boost::hof::detail::pack_get<Ts1, pack_tag<seq<Ns1>, Ts1...>>(BOOST_HOF_FORWARD(P1)(p1))...,
+ boost::hof::detail::pack_get<Ts2, pack_tag<seq<Ns2>, Ts2...>>(BOOST_HOF_FORWARD(P2)(p2))...);
+ }
+};
+
+template<class P1, class P2>
+struct pack_join_result
+: pack_join_base<
+ typename std::remove_cv<typename std::remove_reference<P1>::type>::type,
+ typename std::remove_cv<typename std::remove_reference<P2>::type>::type
+>
+{};
+
+
+struct pack_basic_f
+{
+ template<class... Ts>
+ constexpr auto operator()(Ts&&... xs) const BOOST_HOF_RETURNS
+ (
+ pack_base<typename gens<sizeof...(Ts)>::type, typename remove_rvalue_reference<Ts>::type...>(BOOST_HOF_FORWARD(Ts)(xs)...)
+ );
+};
+
+struct pack_forward_f
+{
+ template<class... Ts>
+ constexpr auto operator()(Ts&&... xs) const BOOST_HOF_RETURNS
+ (
+ pack_base<typename gens<sizeof...(Ts)>::type, Ts&&...>(BOOST_HOF_FORWARD(Ts)(xs)...)
+ );
+};
+
+struct pack_f
+{
+ template<class... Ts>
+ constexpr auto operator()(Ts&&... xs) const BOOST_HOF_RETURNS
+ (
+ pack_basic_f()(boost::hof::decay(BOOST_HOF_FORWARD(Ts)(xs))...)
+ );
+};
+
+template<class P1, class P2>
+constexpr typename pack_join_result<P1, P2>::result_type make_pack_join_dual(P1&& p1, P2&& p2)
+BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(pack_join_result<P1, P2>::call(BOOST_HOF_FORWARD(P1)(p1), BOOST_HOF_FORWARD(P2)(p2)))
+{
+ return pack_join_result<P1, P2>::call(BOOST_HOF_FORWARD(P1)(p1), BOOST_HOF_FORWARD(P2)(p2));
+}
+
+// Manually compute join return type to make older gcc happy
+template<class... Ts>
+struct join_type;
+
+template<class T>
+struct join_type<T>
+{
+ typedef T type;
+};
+
+template<class T, class... Ts>
+struct join_type<T, Ts...>
+{
+ typedef typename pack_join_result<T, typename join_type<Ts...>::type>::result_type type;
+};
+
+template<class P1>
+constexpr P1 make_pack_join(P1&& p1) BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(P1, P1&&)
+{
+ return BOOST_HOF_FORWARD(P1)(p1);
+}
+
+template<class P1, class... Ps>
+constexpr typename join_type<P1, Ps...>::type make_pack_join(P1&& p1, Ps&&... ps)
+BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(make_pack_join_dual(BOOST_HOF_FORWARD(P1)(p1), make_pack_join(BOOST_HOF_FORWARD(Ps)(ps)...)))
+{
+ return make_pack_join_dual(BOOST_HOF_FORWARD(P1)(p1), make_pack_join(BOOST_HOF_FORWARD(Ps)(ps)...));
+}
+
+struct pack_join_f
+{
+
+ template<class... Ps>
+ constexpr auto operator()(Ps&&... ps) const BOOST_HOF_RETURNS
+ (
+ make_pack_join(BOOST_HOF_FORWARD(Ps)(ps)...)
+ );
+};
+
+}
+
+BOOST_HOF_DECLARE_STATIC_VAR(pack_basic, detail::pack_basic_f);
+BOOST_HOF_DECLARE_STATIC_VAR(pack_forward, detail::pack_forward_f);
+BOOST_HOF_DECLARE_STATIC_VAR(pack, detail::pack_f);
+
+BOOST_HOF_DECLARE_STATIC_VAR(pack_join, detail::pack_join_f);
+
+template<class T, class... Ts>
+struct unpack_sequence<detail::pack_base<T, Ts...>>
+{
+ template<class F, class P>
+ constexpr static auto apply(F&& f, P&& p) BOOST_HOF_RETURNS
+ (
+ boost::hof::detail::unpack_pack_base(BOOST_HOF_FORWARD(F)(f), BOOST_HOF_FORWARD(P)(p))
+ );
+};
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/partial.hpp b/boost/hof/partial.hpp
new file mode 100644
index 0000000000..6c1455f663
--- /dev/null
+++ b/boost/hof/partial.hpp
@@ -0,0 +1,292 @@
+/*=============================================================================
+ Copyright (c) 2012 Paul Fultz II
+ partial.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FUNCTION_PARTIAL_H
+#define BOOST_HOF_GUARD_FUNCTION_PARTIAL_H
+
+/// partial
+/// ========
+///
+/// Description
+/// -----------
+///
+/// The `partial` function adaptor allows partial application of the function.
+/// If the function can not be called with all the parameters, it will return
+/// another function. It will repeatedly do this until the function can
+/// finally be called. By default, `partial` captures all of its variables by
+/// value, just like bind. As such all parameters must be `MoveConstructible`
+/// when the function is aprtial application. `std::ref` can be used to
+/// capture references instead.
+///
+/// Synopsis
+/// --------
+///
+/// template<class F>
+/// constexpr partial_adaptor<F> partial(F f);
+///
+/// Semantics
+/// ---------
+///
+/// assert(partial(f)(xs...)(ys...) == f(xs..., ys...));
+///
+/// Requirements
+/// ------------
+///
+/// F must be:
+///
+/// * [ConstInvocable](ConstInvocable)
+/// * MoveConstructible
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+/// using namespace boost::hof;
+///
+/// struct sum
+/// {
+/// template<class T, class U>
+/// T operator()(T x, U y) const
+/// {
+/// return x+y;
+/// }
+/// };
+///
+/// int main() {
+/// assert(3 == partial(sum())(1)(2));
+/// }
+///
+/// References
+/// ----------
+///
+/// * [Partial application](https://en.wikipedia.org/wiki/Partial_application)
+/// * [Currying](https://en.wikipedia.org/wiki/Currying)
+///
+
+#include <boost/hof/first_of.hpp>
+#include <boost/hof/static.hpp>
+#include <boost/hof/pipable.hpp>
+#include <boost/hof/detail/make.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+
+
+namespace boost { namespace hof {
+
+// TODO: Get rid of sequence parameter
+// Forward declare partial_adaptor, since it will be used below
+template<class F, class Pack=void >
+struct partial_adaptor;
+
+BOOST_HOF_DECLARE_STATIC_VAR(partial, detail::make<partial_adaptor>);
+
+namespace detail {
+
+template<class Derived, class F, class Pack>
+struct partial_adaptor_invoke
+{
+ template<class... Ts>
+ constexpr const F& get_function(Ts&&...) const noexcept
+ {
+ return static_cast<const F&>(static_cast<const Derived&>(*this));
+ }
+
+ template<class... Ts>
+ constexpr const Pack& get_pack(Ts&&...) const noexcept
+ {
+ return static_cast<const Pack&>(static_cast<const Derived&>(*this));
+ }
+
+ BOOST_HOF_RETURNS_CLASS(partial_adaptor_invoke);
+
+ template<class... Ts>
+ constexpr BOOST_HOF_SFINAE_RESULT
+ (
+ typename result_of<decltype(boost::hof::pack_join),
+ id_<const Pack&>,
+ result_of<decltype(boost::hof::pack_forward), id_<Ts>...>
+ >::type,
+ id_<F&&>
+ )
+ operator()(Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS
+ (
+ boost::hof::pack_join
+ (
+ BOOST_HOF_MANGLE_CAST(const Pack&)(BOOST_HOF_CONST_THIS->get_pack(xs...)),
+ boost::hof::pack_forward(BOOST_HOF_FORWARD(Ts)(xs)...)
+ )
+ (BOOST_HOF_RETURNS_C_CAST(F&&)(BOOST_HOF_CONST_THIS->get_function(xs...)))
+ );
+};
+
+#ifdef _MSC_VER
+#define BOOST_HOF_PARTIAL_RETURNS(...) -> decltype(__VA_ARGS__) { return (__VA_ARGS__); }
+#else
+#define BOOST_HOF_PARTIAL_RETURNS BOOST_HOF_SFINAE_RETURNS
+#endif
+
+template<class Derived, class F, class Pack>
+struct partial_adaptor_join
+{
+ template<class... Ts>
+ constexpr const F& get_function(Ts&&...) const noexcept
+ {
+ return static_cast<const F&>(static_cast<const Derived&>(*this));
+ }
+
+ template<class... Ts>
+ constexpr const Pack& get_pack(Ts&&...) const noexcept
+ {
+ return static_cast<const Pack&>(static_cast<const Derived&>(*this));
+ }
+
+ BOOST_HOF_RETURNS_CLASS(partial_adaptor_join);
+
+ template<class... Ts, class=typename std::enable_if<
+ ((sizeof...(Ts) + Pack::fit_function_param_limit::value) < function_param_limit<F>::value)
+ >::type>
+ constexpr auto operator()(Ts&&... xs) const
+#ifdef _MSC_VER
+ // Workaround ICE on MSVC
+ noexcept(BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(F, F&&) && noexcept(boost::hof::pack_join(std::declval<const Pack&>(), boost::hof::pack(BOOST_HOF_FORWARD(Ts)(xs)...))))
+#endif
+ BOOST_HOF_PARTIAL_RETURNS
+ (
+ boost::hof::partial
+ (
+ BOOST_HOF_RETURNS_C_CAST(F&&)(BOOST_HOF_CONST_THIS->get_function(xs...)),
+ boost::hof::pack_join(BOOST_HOF_MANGLE_CAST(const Pack&)(BOOST_HOF_CONST_THIS->get_pack(xs...)), boost::hof::pack(BOOST_HOF_FORWARD(Ts)(xs)...))
+ )
+ );
+};
+
+template<class Derived, class F>
+struct partial_adaptor_pack
+{
+
+ constexpr partial_adaptor_pack() noexcept
+ {}
+
+ template<class... Ts>
+ constexpr const F& get_function(Ts&&...) const noexcept
+ {
+ return static_cast<const F&>(static_cast<const Derived&>(*this));
+ }
+
+ BOOST_HOF_RETURNS_CLASS(partial_adaptor_pack);
+
+ template<class... Ts, class=typename std::enable_if<
+ (sizeof...(Ts) < function_param_limit<F>::value)
+ >::type>
+ constexpr auto operator()(Ts&&... xs) const
+#ifdef _MSC_VER
+ // Workaround ICE on MSVC
+ noexcept(BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(F, F&&) && noexcept(boost::hof::pack(BOOST_HOF_FORWARD(Ts)(xs)...)))
+#endif
+ BOOST_HOF_PARTIAL_RETURNS
+ (
+ boost::hof::partial
+ (
+ BOOST_HOF_RETURNS_C_CAST(F&&)(BOOST_HOF_CONST_THIS->get_function(xs...)),
+ boost::hof::pack(BOOST_HOF_FORWARD(Ts)(xs)...)
+ )
+ );
+};
+template<class F, class Pack>
+struct partial_adaptor_base
+{
+ typedef basic_first_of_adaptor
+ <
+ partial_adaptor_invoke<partial_adaptor<F, Pack>, F, Pack>,
+ partial_adaptor_join<partial_adaptor<F, Pack>, F, Pack>
+ > type;
+};
+
+template<class Derived, class F>
+struct partial_adaptor_pack_base
+{
+ typedef basic_first_of_adaptor
+ <
+ F,
+ partial_adaptor_pack<Derived, F>
+ > type;
+};
+
+}
+
+template<class F, class Pack>
+struct partial_adaptor : detail::partial_adaptor_base<F, Pack>::type, F, Pack
+{
+ typedef typename detail::partial_adaptor_base<F, Pack>::type base;
+
+ typedef partial_adaptor fit_rewritable1_tag;
+
+ template<class... Ts>
+ constexpr const F& base_function(Ts&&...) const noexcept
+ {
+ return *this;
+ }
+
+ constexpr const Pack& get_pack() const noexcept
+ {
+ return *this;
+ }
+
+ using base::operator();
+
+ BOOST_HOF_INHERIT_DEFAULT(partial_adaptor, base, F, Pack);
+
+ template<class X, class S>
+ constexpr partial_adaptor(X&& x, S&& seq)
+ BOOST_HOF_NOEXCEPT(BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(F, X&&) && BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(Pack, S&&))
+ : F(BOOST_HOF_FORWARD(X)(x)), Pack(BOOST_HOF_FORWARD(S)(seq))
+ {}
+};
+
+template<class F>
+struct partial_adaptor<F, void> : detail::partial_adaptor_pack_base<partial_adaptor<F, void>, detail::callable_base<F>>::type
+{
+ typedef typename detail::partial_adaptor_pack_base<partial_adaptor<F, void>, detail::callable_base<F>>::type base;
+
+ typedef partial_adaptor fit_rewritable1_tag;
+
+ template<class... Ts>
+ constexpr const detail::callable_base<F>& base_function(Ts&&...) const noexcept
+ {
+ return *this;
+ }
+
+ using base::operator();
+
+ BOOST_HOF_INHERIT_CONSTRUCTOR(partial_adaptor, base);
+
+};
+
+// Make partial_adaptor work with pipable_adaptor by removing its pipableness
+template<class F>
+struct partial_adaptor<pipable_adaptor<F>, void>
+: partial_adaptor<F, void>
+{
+ typedef partial_adaptor<F, void> base;
+
+ typedef partial_adaptor fit_rewritable1_tag;
+ BOOST_HOF_INHERIT_CONSTRUCTOR(partial_adaptor, base);
+};
+
+template<class F>
+struct partial_adaptor<static_<pipable_adaptor<F>>, void>
+: partial_adaptor<F, void>
+{
+ typedef partial_adaptor<F, void> base;
+
+ typedef partial_adaptor fit_rewritable1_tag;
+
+ BOOST_HOF_INHERIT_CONSTRUCTOR(partial_adaptor, base);
+};
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/pipable.hpp b/boost/hof/pipable.hpp
new file mode 100644
index 0000000000..9f699ec9c4
--- /dev/null
+++ b/boost/hof/pipable.hpp
@@ -0,0 +1,215 @@
+/*=============================================================================
+ Copyright (c) 2012 Paul Fultz II
+ pipable.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FUNCTION_PIPABLE_H
+#define BOOST_HOF_GUARD_FUNCTION_PIPABLE_H
+
+/// pipable
+/// =======
+///
+/// Description
+/// -----------
+///
+/// The `pipable` function adaptor provides an extension method. The first
+/// parameter of the function can be piped into the function using the pipe
+/// `|` operator. This can be especially convenient when there are a lot of
+/// nested function calls. Functions that are made pipable can still be called
+/// the traditional way without piping in the first parameter.
+///
+/// Synopsis
+/// --------
+///
+/// template<class F>
+/// constexpr pipable_adaptor<F> pipable(F f);
+///
+/// Semantics
+/// ---------
+///
+/// assert(x | pipable(f)(ys...) == f(x, ys...));
+///
+/// Requirements
+/// ------------
+///
+/// F must be:
+///
+/// * [ConstInvocable](ConstInvocable)
+/// * MoveConstructible
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+/// using namespace boost::hof;
+///
+/// struct sum
+/// {
+/// template<class T, class U>
+/// T operator()(T x, U y) const
+/// {
+/// return x+y;
+/// }
+/// };
+///
+/// int main() {
+/// assert(3 == (1 | pipable(sum())(2)));
+/// assert(3 == pipable(sum())(1, 2));
+/// }
+///
+/// References
+/// ----------
+///
+/// * [Extension methods](<Extension methods>)
+///
+
+#include <boost/hof/first_of.hpp>
+#include <boost/hof/pack.hpp>
+#include <boost/hof/detail/delegate.hpp>
+#include <boost/hof/detail/move.hpp>
+#include <boost/hof/detail/make.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+#include <boost/hof/limit.hpp>
+
+namespace boost { namespace hof {
+
+template<class F>
+struct pipable_adaptor;
+
+namespace detail {
+
+template<class F, class Pack>
+struct pipe_closure : F, Pack
+{
+
+ template<class X, class P>
+ constexpr pipe_closure(X&& fp, P&& packp)
+ BOOST_HOF_NOEXCEPT(BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(F, X&&) && BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(Pack, P&&))
+ : F(BOOST_HOF_FORWARD(X)(fp)), Pack(BOOST_HOF_FORWARD(P)(packp))
+ {}
+
+ template<class... Ts>
+ constexpr const F& base_function(Ts&&...) const noexcept
+ {
+ return *this;
+ }
+
+ template<class... Ts>
+ constexpr const Pack& get_pack(Ts&&...) const noexcept
+ {
+ return *this;
+ }
+
+ template<class A>
+ struct invoke
+ {
+ A a;
+ const pipe_closure * self;
+ template<class X>
+ constexpr invoke(X&& xp, const pipe_closure * selfp)
+ BOOST_HOF_NOEXCEPT(BOOST_HOF_IS_NOTHROW_CONSTRUCTIBLE(A, X&&))
+ : a(BOOST_HOF_FORWARD(X)(xp)), self(selfp)
+ {}
+
+ BOOST_HOF_RETURNS_CLASS(invoke);
+
+ template<class... Ts>
+ constexpr BOOST_HOF_SFINAE_RESULT(const F&, id_<A>, id_<Ts>...)
+ operator()(Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS
+ (BOOST_HOF_RETURNS_STATIC_CAST(const F&)(*BOOST_HOF_CONST_THIS->self)(BOOST_HOF_FORWARD(A)(a), BOOST_HOF_FORWARD(Ts)(xs)...));
+ };
+
+ BOOST_HOF_RETURNS_CLASS(pipe_closure);
+
+ template<class A>
+ constexpr BOOST_HOF_SFINAE_RESULT(const Pack&, id_<invoke<A&&>>)
+ operator()(A&& a) const BOOST_HOF_SFINAE_RETURNS
+ (BOOST_HOF_MANGLE_CAST(const Pack&)(BOOST_HOF_CONST_THIS->get_pack(a))(invoke<A&&>(BOOST_HOF_FORWARD(A)(a), BOOST_HOF_CONST_THIS)));
+};
+
+template<class F, class Pack>
+constexpr auto make_pipe_closure(F f, Pack&& p) BOOST_HOF_RETURNS
+(
+ pipe_closure<F, typename std::remove_reference<Pack>::type>(BOOST_HOF_RETURNS_STATIC_CAST(F&&)(f), BOOST_HOF_FORWARD(Pack)(p))
+);
+
+
+template<class Derived, class F>
+struct pipe_pack
+{
+ template<class... Ts>
+ constexpr const F& get_function(Ts&&...) const noexcept
+ {
+ return static_cast<const F&>(static_cast<const Derived&>(*this));
+ }
+
+ BOOST_HOF_RETURNS_CLASS(pipe_pack);
+
+ template<class... Ts, class=typename std::enable_if<
+ (sizeof...(Ts) < function_param_limit<F>::value)
+ >::type>
+ constexpr auto operator()(Ts&&... xs) const BOOST_HOF_RETURNS
+ (make_pipe_closure(BOOST_HOF_RETURNS_C_CAST(F&&)(BOOST_HOF_CONST_THIS->get_function(xs...)), boost::hof::pack_forward(BOOST_HOF_FORWARD(Ts)(xs)...)));
+};
+
+template<class A, class F, class Pack>
+constexpr auto operator|(A&& a, const pipe_closure<F, Pack>& p) BOOST_HOF_RETURNS
+(p(BOOST_HOF_FORWARD(A)(a)));
+
+}
+
+template<class F>
+struct pipable_adaptor
+: detail::basic_first_of_adaptor<detail::callable_base<F>, detail::pipe_pack<pipable_adaptor<F>, detail::callable_base<F>> >
+{
+ typedef detail::basic_first_of_adaptor<detail::callable_base<F>, detail::pipe_pack<pipable_adaptor<F>, detail::callable_base<F>> > base;
+ typedef pipable_adaptor fit_rewritable_tag;
+
+ BOOST_HOF_INHERIT_CONSTRUCTOR(pipable_adaptor, base);
+
+ constexpr const detail::callable_base<F>& base_function() const noexcept
+ {
+ return *this;
+ }
+};
+
+template<class A, class F>
+constexpr auto operator|(A&& a, const pipable_adaptor<F>& p) BOOST_HOF_RETURNS
+(p(BOOST_HOF_FORWARD(A)(a)));
+
+BOOST_HOF_DECLARE_STATIC_VAR(pipable, detail::make<pipable_adaptor>);
+
+namespace detail {
+
+template<class F>
+struct static_function_wrapper;
+
+// Operators for static_function_wrapper adaptor
+template<class A, class F>
+auto operator|(A&& a, const boost::hof::detail::static_function_wrapper<F>& f) BOOST_HOF_RETURNS
+(f(BOOST_HOF_FORWARD(A)(a)));
+
+template<class F>
+struct static_default_function;
+
+// Operators for static_default_function adaptor
+template<class A, class F>
+auto operator|(A&& a, const boost::hof::detail::static_default_function<F>& f) BOOST_HOF_RETURNS
+(f(BOOST_HOF_FORWARD(A)(a)));
+
+}
+
+template<class F>
+struct static_;
+
+// Operators for static_ adaptor
+template<class A, class F>
+auto operator|(A&& a, static_<F> f) BOOST_HOF_RETURNS
+(f.base_function().base_function()(BOOST_HOF_FORWARD(A)(a)));
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/placeholders.hpp b/boost/hof/placeholders.hpp
new file mode 100644
index 0000000000..42e4a58b48
--- /dev/null
+++ b/boost/hof/placeholders.hpp
@@ -0,0 +1,468 @@
+/*=============================================================================
+ Copyright (c) 2014 Paul Fultz II
+ placeholders.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FUNCTION_PLACEHOLDERS_H
+#define BOOST_HOF_GUARD_FUNCTION_PLACEHOLDERS_H
+
+/// placeholders
+/// ============
+///
+/// Description
+/// -----------
+///
+/// The placeholders provide `std::bind` compatible placeholders that
+/// additionally provide basic C++ operators that creates bind expressions.
+/// Each bind expression supports `constexpr` function evaluation.
+///
+/// Synopsis
+/// --------
+///
+/// namespace placeholders {
+/// placeholder<1> _1 = {};
+/// placeholder<2> _2 = {};
+/// placeholder<3> _3 = {};
+/// placeholder<4> _4 = {};
+/// placeholder<5> _5 = {};
+/// placeholder<6> _6 = {};
+/// placeholder<7> _7 = {};
+/// placeholder<8> _8 = {};
+/// placeholder<9> _9 = {};
+/// }
+///
+/// Operators
+/// ---------
+///
+/// * Binary operators: +,-,*,/,%,>>,<<,>,<,<=,>=,==,!=,&,^,|,&&,||
+/// * Assign operators: +=,-=,*=,/=,%=,>>=,<<=,&=,|=,^=
+/// * Unary operators: !,~,+,-,*,++,--
+///
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+/// using namespace boost::hof;
+///
+/// int main() {
+/// auto sum = _1 + _2;
+/// assert(3 == sum(1, 2));
+/// }
+///
+///
+/// unamed placeholder
+/// ==================
+///
+/// Description
+/// -----------
+///
+/// The unamed placeholder can be used to build simple functions from C++
+/// operators.
+///
+/// Note: The function produced by the unamed placeholder is not a bind expression.
+///
+/// Synopsis
+/// --------
+///
+/// namespace placeholders {
+/// /* unspecified */ _ = {};
+/// }
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+/// using namespace boost::hof;
+///
+/// int main() {
+/// auto sum = _ + _;
+/// assert(3 == sum(1, 2));
+/// }
+///
+
+#include <boost/hof/returns.hpp>
+#include <boost/hof/lazy.hpp>
+#include <boost/hof/protect.hpp>
+
+#if defined(_MSC_VER) && _MSC_VER >= 1910
+#include <boost/hof/detail/pp.hpp>
+#endif
+
+namespace boost { namespace hof { namespace detail {
+ template<int N>
+ struct simple_placeholder
+ {};
+}}} // namespace boost::hof
+
+namespace std {
+ template<int N>
+ struct is_placeholder<boost::hof::detail::simple_placeholder<N>>
+ : std::integral_constant<int, N>
+ {};
+}
+
+
+namespace boost { namespace hof {
+
+#define BOOST_HOF_FOREACH_BINARY_OP(m) \
+ m(+, add) \
+ m(-, subtract) \
+ m(*, multiply) \
+ m(/, divide) \
+ m(%, remainder) \
+ m(>>, shift_right) \
+ m(<<, shift_left) \
+ m(>, greater_than) \
+ m(<, less_than) \
+ m(<=, less_than_equal) \
+ m(>=, greater_than_equal) \
+ m(==, equal) \
+ m(!=, not_equal) \
+ m(&, bit_and) \
+ m(^, xor_) \
+ m(|, bit_or) \
+ m(&&, and_) \
+ m(||, or_)
+
+#define BOOST_HOF_FOREACH_ASSIGN_OP(m) \
+ m(+=, assign_add) \
+ m(-=, assign_subtract) \
+ m(*=, assign_multiply) \
+ m(/=, assign_divide) \
+ m(%=, assign_remainder) \
+ m(>>=, assign_right_shift) \
+ m(<<=, assign_left_shift) \
+ m(&=, assign_bit_and) \
+ m(|=, assign_bit_or) \
+ m(^=, assign_xor)
+
+#ifndef _MSC_VER
+#define BOOST_HOF_FOREACH_UNARY_OP(m) \
+ m(!, not_) \
+ m(~, compl_) \
+ m(+, unary_plus) \
+ m(-, unary_subtract) \
+ m(*, dereference) \
+ m(++, increment) \
+ m(--, decrement)
+#else
+#define BOOST_HOF_FOREACH_UNARY_OP(m) \
+ m(!, not_) \
+ m(~, compl_) \
+ m(+, unary_plus) \
+ m(-, unary_subtract) \
+ m(*, dereference)
+#endif
+
+namespace operators {
+
+struct call
+{
+ template<class F, class... Ts>
+ constexpr auto operator()(F&& f, Ts&&... xs) const BOOST_HOF_RETURNS
+ (f(BOOST_HOF_FORWARD(Ts)(xs)...));
+};
+
+// MSVC 2017 ICEs on && and || in conxtexpr, so we fallback on bitwise operators
+#if defined(_MSC_VER) && _MSC_VER >= 1910
+#define BOOST_HOF_BINARY_OP_SKIP_and_ ()
+#define BOOST_HOF_BINARY_OP_SKIP_or_ ()
+
+struct and_
+{
+ template<class T, class U>
+ constexpr auto operator()(T&& x, U&& y) const
+ noexcept(noexcept(BOOST_HOF_FORWARD(T)(x) && BOOST_HOF_FORWARD(U)(y)))
+ -> decltype(BOOST_HOF_FORWARD(T)(x) && BOOST_HOF_FORWARD(U)(y))
+ { return BOOST_HOF_FORWARD(T)(x) & BOOST_HOF_FORWARD(U)(y); }
+};
+
+struct or_
+{
+ template<class T, class U>
+ constexpr auto operator()(T&& x, U&& y) const
+ noexcept(noexcept(BOOST_HOF_FORWARD(T)(x) || BOOST_HOF_FORWARD(U)(y)))
+ -> decltype(BOOST_HOF_FORWARD(T)(x) || BOOST_HOF_FORWARD(U)(y))
+ { return BOOST_HOF_FORWARD(T)(x) | BOOST_HOF_FORWARD(U)(y); }
+};
+
+#define BOOST_HOF_BINARY_OP_IMPL(op, name) \
+ struct name \
+ { \
+ template<class T, class U> \
+ BOOST_HOF_USING(ex_failure, decltype(std::declval<T>() op std::declval<U>())); \
+ struct failure : as_failure<ex_failure> {}; \
+ template<class T, class U> \
+ constexpr auto operator()(T&& x, U&& y) const BOOST_HOF_RETURNS \
+ (BOOST_HOF_FORWARD(T)(x) op BOOST_HOF_FORWARD(U)(y)); \
+ };
+
+#define BOOST_HOF_BINARY_OP(op, name) \
+ BOOST_HOF_PP_IIF(BOOST_HOF_PP_IS_PAREN(BOOST_HOF_PP_CAT(BOOST_HOF_BINARY_OP_SKIP_, name))) \
+ (BOOST_HOF_PP_EMPTY, BOOST_HOF_BINARY_OP_IMPL)(op, name)
+
+#else
+
+#define BOOST_HOF_BINARY_OP(op, name) \
+ struct name \
+ { \
+ template<class T, class U> \
+ constexpr auto operator()(T&& x, U&& y) const BOOST_HOF_RETURNS \
+ (BOOST_HOF_FORWARD(T)(x) op BOOST_HOF_FORWARD(U)(y)); \
+ };
+
+#endif
+
+BOOST_HOF_FOREACH_BINARY_OP(BOOST_HOF_BINARY_OP)
+BOOST_HOF_FOREACH_ASSIGN_OP(BOOST_HOF_BINARY_OP)
+
+#define BOOST_HOF_UNARY_OP(op, name) \
+ struct name \
+ { \
+ template<class T> \
+ constexpr auto operator()(T&& x) const BOOST_HOF_RETURNS \
+ (op(BOOST_HOF_FORWARD(T)(x))); \
+ };
+
+
+BOOST_HOF_FOREACH_UNARY_OP(BOOST_HOF_UNARY_OP)
+
+
+}
+
+template<int N>
+struct placeholder
+{
+#if BOOST_HOF_HAS_MANGLE_OVERLOAD
+ template<class... Ts>
+ constexpr auto operator()(Ts&&... xs) const BOOST_HOF_RETURNS
+ ( boost::hof::lazy(operators::call())(detail::simple_placeholder<N>(), BOOST_HOF_FORWARD(Ts)(xs)...) );
+#else
+ template<class... Ts>
+ struct result_call
+ { typedef decltype(boost::hof::lazy(operators::call())(detail::simple_placeholder<N>(), std::declval<Ts>()...)) type; };
+ template<class... Ts>
+ constexpr typename result_call<Ts...>::type operator()(Ts&&... xs) const
+ { return boost::hof::lazy(operators::call())(detail::simple_placeholder<N>(), BOOST_HOF_FORWARD(Ts)(xs)...); };
+
+#endif
+
+#define BOOST_HOF_PLACEHOLDER_UNARY_OP(op, name) \
+ constexpr auto operator op () const BOOST_HOF_RETURNS \
+ ( boost::hof::lazy(operators::name())(detail::simple_placeholder<N>()) );
+
+BOOST_HOF_FOREACH_UNARY_OP(BOOST_HOF_PLACEHOLDER_UNARY_OP)
+
+#define BOOST_HOF_PLACEHOLDER_ASSIGN_OP(op, name) \
+ template<class T> \
+ constexpr auto operator op (T&& x) const BOOST_HOF_RETURNS \
+ ( boost::hof::lazy(operators::name())(detail::simple_placeholder<N>(), BOOST_HOF_FORWARD(T)(x)) );
+
+BOOST_HOF_FOREACH_ASSIGN_OP(BOOST_HOF_PLACEHOLDER_ASSIGN_OP)
+
+};
+
+#if BOOST_HOF_HAS_MANGLE_OVERLOAD
+
+#define BOOST_HOF_PLACEHOLDER_BINARY_OP(op, name) \
+ template<class T, int N> \
+ constexpr inline auto operator op (const placeholder<N>&, T&& x) BOOST_HOF_RETURNS \
+ ( boost::hof::lazy(operators::name())(detail::simple_placeholder<N>(), BOOST_HOF_FORWARD(T)(x)) ); \
+ template<class T, int N> \
+ constexpr inline auto operator op (T&& x, const placeholder<N>&) BOOST_HOF_RETURNS \
+ ( boost::hof::lazy(operators::name())(BOOST_HOF_FORWARD(T)(x), detail::simple_placeholder<N>()) ); \
+ template<int N, int M> \
+ constexpr inline auto operator op (const placeholder<N>&, const placeholder<M>&) BOOST_HOF_RETURNS \
+ ( boost::hof::lazy(operators::name())(detail::simple_placeholder<N>(), detail::simple_placeholder<M>()) );
+
+#else
+
+#define BOOST_HOF_PLACEHOLDER_BINARY_OP(op, name) \
+ template<class T, class U> \
+ struct result_ ## name \
+ { typedef decltype(boost::hof::lazy(operators::name())(std::declval<T>(), std::declval<U>())) type; }; \
+ template<class T, int N> \
+ constexpr inline typename result_ ## name<detail::simple_placeholder<N>, T>::type operator op (const placeholder<N>&, T&& x) \
+ { return boost::hof::lazy(operators::name())(detail::simple_placeholder<N>(), BOOST_HOF_FORWARD(T)(x)); } \
+ template<class T, int N> \
+ constexpr inline typename result_ ## name<T, detail::simple_placeholder<N>>::type operator op (T&& x, const placeholder<N>&) \
+ { return boost::hof::lazy(operators::name())(BOOST_HOF_FORWARD(T)(x), detail::simple_placeholder<N>()); } \
+ template<int N, int M> \
+ constexpr inline typename result_ ## name<detail::simple_placeholder<N>, detail::simple_placeholder<M>>::type operator op (const placeholder<N>&, const placeholder<M>&) \
+ { return boost::hof::lazy(operators::name())(detail::simple_placeholder<N>(), detail::simple_placeholder<M>()); }
+
+#endif
+
+BOOST_HOF_FOREACH_BINARY_OP(BOOST_HOF_PLACEHOLDER_BINARY_OP)
+
+namespace placeholders {
+BOOST_HOF_DECLARE_STATIC_VAR(_1, placeholder<1>);
+BOOST_HOF_DECLARE_STATIC_VAR(_2, placeholder<2>);
+BOOST_HOF_DECLARE_STATIC_VAR(_3, placeholder<3>);
+BOOST_HOF_DECLARE_STATIC_VAR(_4, placeholder<4>);
+BOOST_HOF_DECLARE_STATIC_VAR(_5, placeholder<5>);
+BOOST_HOF_DECLARE_STATIC_VAR(_6, placeholder<6>);
+BOOST_HOF_DECLARE_STATIC_VAR(_7, placeholder<7>);
+BOOST_HOF_DECLARE_STATIC_VAR(_8, placeholder<8>);
+BOOST_HOF_DECLARE_STATIC_VAR(_9, placeholder<9>);
+}
+
+using placeholders::_1;
+using placeholders::_2;
+using placeholders::_3;
+using placeholders::_4;
+using placeholders::_5;
+using placeholders::_6;
+using placeholders::_7;
+using placeholders::_8;
+using placeholders::_9;
+
+namespace detail {
+
+
+
+struct unamed_placeholder
+{
+template<class T, class Invoker>
+struct partial_ap
+{
+ T val;
+
+ BOOST_HOF_INHERIT_DEFAULT_EMPTY(partial_ap, T)
+
+ template<class X, class... Xs, BOOST_HOF_ENABLE_IF_CONSTRUCTIBLE(T, X&&, Xs&&...)>
+ constexpr partial_ap(X&& x, Xs&&... xs) : val(BOOST_HOF_FORWARD(X)(x), BOOST_HOF_FORWARD(Xs)(xs)...)
+ {}
+
+ BOOST_HOF_RETURNS_CLASS(partial_ap);
+
+ struct partial_ap_failure
+ {
+ template<class Failure>
+ struct apply
+ {
+ template<class... Xs>
+ struct of;
+
+ template<class X>
+ struct of<X>
+ : Failure::template of<typename std::add_const<T>::type, X>
+ {};
+ };
+ };
+
+ struct failure
+ : failure_map<partial_ap_failure, Invoker>
+ {};
+
+ template<class X>
+ constexpr BOOST_HOF_SFINAE_RESULT(const Invoker&, id_<T>, id_<X>)
+ operator()(X&& x) const BOOST_HOF_SFINAE_RETURNS
+ (
+ Invoker()(BOOST_HOF_CONST_THIS->val, BOOST_HOF_FORWARD(X)(x))
+ );
+};
+
+template<class Invoker, class T>
+static constexpr partial_ap<T, Invoker> make_partial_ap(T&& x)
+{
+ return {BOOST_HOF_FORWARD(T)(x)};
+}
+
+template<class Op>
+struct left
+{
+ struct failure
+ : failure_for<Op>
+ {};
+ template<class T, class X>
+ constexpr BOOST_HOF_SFINAE_RESULT(const Op&, id_<T>, id_<X>)
+ operator()(T&& val, X&& x) const BOOST_HOF_SFINAE_RETURNS
+ (Op()(BOOST_HOF_FORWARD(T)(val), BOOST_HOF_FORWARD(X)(x)));
+};
+
+template<class Op>
+struct right
+{
+ struct right_failure
+ {
+ template<class Failure>
+ struct apply
+ {
+ template<class T, class U, class... Ts>
+ struct of
+ : Failure::template of<U, T, Ts...>
+ {};
+ };
+ };
+
+ struct failure
+ : failure_map<right_failure, Op>
+ {};
+
+ template<class T, class X>
+ constexpr BOOST_HOF_SFINAE_RESULT(const Op&, id_<X>, id_<T>)
+ operator()(T&& val, X&& x) const BOOST_HOF_SFINAE_RETURNS
+ (Op()(BOOST_HOF_FORWARD(X)(x), BOOST_HOF_FORWARD(T)(val)));
+};
+
+#define BOOST_HOF_UNAMED_PLACEHOLDER_UNARY_OP(op, name) \
+ constexpr auto operator op () const BOOST_HOF_RETURNS \
+ ( operators::name() );
+
+BOOST_HOF_FOREACH_UNARY_OP(BOOST_HOF_UNAMED_PLACEHOLDER_UNARY_OP)
+
+#define BOOST_HOF_UNAMED_PLACEHOLDER_ASSIGN_OP(op, name) \
+ template<class T> \
+ constexpr auto operator op (const T& x) const BOOST_HOF_RETURNS \
+ ( partial_ap<T, left<operators::name>>(x) );
+
+BOOST_HOF_FOREACH_ASSIGN_OP(BOOST_HOF_UNAMED_PLACEHOLDER_ASSIGN_OP)
+};
+#define BOOST_HOF_UNAMED_PLACEHOLDER_BINARY_OP(op, name) \
+ template<class T> \
+ constexpr inline auto operator op (const unamed_placeholder&, const T& x) BOOST_HOF_RETURNS \
+ ( unamed_placeholder::make_partial_ap<unamed_placeholder::right<operators::name>>(boost::hof::decay(x)) ); \
+ template<class T> \
+ constexpr inline auto operator op (const T& x, const unamed_placeholder&) BOOST_HOF_RETURNS \
+ ( unamed_placeholder::make_partial_ap<unamed_placeholder::left<operators::name>>(boost::hof::decay(x)) ); \
+ constexpr inline auto operator op (const unamed_placeholder&, const unamed_placeholder&) BOOST_HOF_RETURNS \
+ ( operators::name() );
+
+BOOST_HOF_FOREACH_BINARY_OP(BOOST_HOF_UNAMED_PLACEHOLDER_BINARY_OP)
+}
+
+namespace placeholders {
+BOOST_HOF_DECLARE_STATIC_VAR(_, detail::unamed_placeholder);
+}
+
+using placeholders::_;
+
+}} // namespace boost::hof
+
+namespace std {
+ template<int N>
+ struct is_placeholder<boost::hof::placeholder<N>>
+ : std::integral_constant<int, N>
+ {};
+}
+
+namespace boost {
+
+ template<class T>
+ struct is_placeholder;
+
+ template<int N>
+ struct is_placeholder<boost::hof::placeholder<N>>
+ : std::integral_constant<int, N>
+ {};
+
+
+}
+
+#endif
diff --git a/boost/hof/proj.hpp b/boost/hof/proj.hpp
new file mode 100644
index 0000000000..6469186c87
--- /dev/null
+++ b/boost/hof/proj.hpp
@@ -0,0 +1,265 @@
+/*=============================================================================
+ Copyright (c) 2014 Paul Fultz II
+ proj.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FUNCTION_ON_H
+#define BOOST_HOF_GUARD_FUNCTION_ON_H
+
+/// proj
+/// ====
+///
+/// Description
+/// -----------
+///
+/// The `proj` function adaptor applies a projection onto the parameters of
+/// another function. This is useful, for example, to define a function for
+/// sorting such that the ordering is based off of the value of one of its
+/// member fields.
+///
+/// Also, if just a projection is given, then the projection will be called
+/// for each of its arguments.
+///
+/// Note: All projections are always evaluated in order from left-to-right.
+///
+/// Synopsis
+/// --------
+///
+/// template<class Projection, class F>
+/// constexpr proj_adaptor<Projection, F> by(Projection p, F f);
+///
+/// template<class Projection>
+/// constexpr proj_adaptor<Projection> by(Projection p);
+///
+/// Semantics
+/// ---------
+///
+/// assert(by(p, f)(xs...) == f(p(xs)...));
+/// assert(by(p)(xs...) == p(xs)...);
+///
+/// Requirements
+/// ------------
+///
+/// Projection must be:
+///
+/// * [UnaryInvocable](UnaryInvocable)
+/// * MoveConstructible
+///
+/// F must be:
+///
+/// * [ConstInvocable](ConstInvocable)
+/// * MoveConstructible
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+/// using namespace boost::hof;
+///
+/// struct foo
+/// {
+/// foo(int x_) : x(x_)
+/// {}
+/// int x;
+/// };
+///
+/// int main() {
+/// assert(boost::hof::proj(&foo::x, _ + _)(foo(1), foo(2)) == 3);
+/// }
+///
+/// References
+/// ----------
+///
+/// * [Projections](Projections)
+/// * [Variadic print](<Variadic print>)
+///
+
+
+
+#include <utility>
+#include <boost/hof/always.hpp>
+#include <boost/hof/detail/callable_base.hpp>
+#include <boost/hof/detail/result_of.hpp>
+#include <boost/hof/detail/move.hpp>
+#include <boost/hof/detail/make.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+#include <boost/hof/detail/compressed_pair.hpp>
+#include <boost/hof/detail/result_type.hpp>
+#include <boost/hof/apply_eval.hpp>
+
+namespace boost { namespace hof {
+
+namespace detail {
+
+template<class T, class Projection>
+struct project_eval
+{
+ T&& x;
+ const Projection& p;
+
+ template<class X, class P>
+ constexpr project_eval(X&& xp, const P& pp) : x(BOOST_HOF_FORWARD(X)(xp)), p(pp)
+ {}
+
+ constexpr auto operator()() const BOOST_HOF_RETURNS
+ (p(BOOST_HOF_FORWARD(T)(x)));
+};
+
+template<class T, class Projection>
+constexpr project_eval<T, Projection> make_project_eval(T&& x, const Projection& p)
+{
+ return project_eval<T, Projection>(BOOST_HOF_FORWARD(T)(x), p);
+}
+
+template<class T, class Projection>
+struct project_void_eval
+{
+ T&& x;
+ const Projection& p;
+
+ template<class X, class P>
+ constexpr project_void_eval(X&& xp, const P& pp) : x(BOOST_HOF_FORWARD(X)(xp)), p(pp)
+ {}
+
+ struct void_ {};
+
+ constexpr void_ operator()() const
+ {
+ return p(BOOST_HOF_FORWARD(T)(x)), void_();
+ }
+};
+
+template<class T, class Projection>
+constexpr project_void_eval<T, Projection> make_project_void_eval(T&& x, const Projection& p)
+{
+ return project_void_eval<T, Projection>(BOOST_HOF_FORWARD(T)(x), p);
+}
+
+template<class Projection, class F, class... Ts,
+ class R=decltype(
+ std::declval<const F&>()(std::declval<const Projection&>()(std::declval<Ts>())...)
+ )>
+constexpr R by_eval(const Projection& p, const F& f, Ts&&... xs)
+{
+ return boost::hof::apply_eval(f, make_project_eval(BOOST_HOF_FORWARD(Ts)(xs), p)...);
+}
+
+#if BOOST_HOF_NO_ORDERED_BRACE_INIT
+#define BOOST_HOF_BY_VOID_RETURN BOOST_HOF_ALWAYS_VOID_RETURN
+#else
+#if BOOST_HOF_NO_CONSTEXPR_VOID
+#define BOOST_HOF_BY_VOID_RETURN boost::hof::detail::swallow
+#else
+#define BOOST_HOF_BY_VOID_RETURN void
+#endif
+#endif
+
+template<class Projection, class... Ts>
+constexpr BOOST_HOF_ALWAYS_VOID_RETURN by_void_eval(const Projection& p, Ts&&... xs)
+{
+ return boost::hof::apply_eval(boost::hof::always(), boost::hof::detail::make_project_void_eval(BOOST_HOF_FORWARD(Ts)(xs), p)...);
+}
+
+struct swallow
+{
+ template<class... Ts>
+ constexpr swallow(Ts&&...)
+ {}
+};
+
+}
+
+template<class Projection, class F=void>
+struct proj_adaptor;
+
+template<class Projection, class F>
+struct proj_adaptor : detail::compressed_pair<detail::callable_base<Projection>, detail::callable_base<F>>, detail::function_result_type<F>
+{
+ typedef proj_adaptor fit_rewritable_tag;
+ typedef detail::compressed_pair<detail::callable_base<Projection>, detail::callable_base<F>> base;
+ template<class... Ts>
+ constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const
+ {
+ return this->second(xs...);;
+ }
+
+ template<class... Ts>
+ constexpr const detail::callable_base<Projection>& base_projection(Ts&&... xs) const
+ {
+ return this->first(xs...);
+ }
+
+ struct by_failure
+ {
+ template<class Failure>
+ struct apply
+ {
+ template<class... Ts>
+ struct of
+ : Failure::template of<decltype(std::declval<detail::callable_base<Projection>>()(std::declval<Ts>()))...>
+ {};
+ };
+ };
+
+ struct failure
+ : failure_map<by_failure, detail::callable_base<F>>
+ {};
+
+ BOOST_HOF_INHERIT_CONSTRUCTOR(proj_adaptor, base)
+
+ BOOST_HOF_RETURNS_CLASS(proj_adaptor);
+
+ template<class... Ts>
+ constexpr BOOST_HOF_SFINAE_RESULT(const detail::callable_base<F>&, result_of<const detail::callable_base<Projection>&, id_<Ts>>...)
+ operator()(Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS
+ (
+ boost::hof::detail::by_eval(
+ BOOST_HOF_MANGLE_CAST(const detail::callable_base<Projection>&)(BOOST_HOF_CONST_THIS->base_projection(xs...)),
+ BOOST_HOF_MANGLE_CAST(const detail::callable_base<F>&)(BOOST_HOF_CONST_THIS->base_function(xs...)),
+ BOOST_HOF_FORWARD(Ts)(xs)...
+ )
+ );
+};
+
+template<class Projection>
+struct proj_adaptor<Projection, void> : detail::callable_base<Projection>
+{
+ typedef proj_adaptor fit_rewritable1_tag;
+ template<class... Ts>
+ constexpr const detail::callable_base<Projection>& base_projection(Ts&&... xs) const
+ {
+ return boost::hof::always_ref(*this)(xs...);
+ }
+
+ BOOST_HOF_INHERIT_DEFAULT(proj_adaptor, detail::callable_base<Projection>)
+
+ template<class P, BOOST_HOF_ENABLE_IF_CONVERTIBLE(P, detail::callable_base<Projection>)>
+ constexpr proj_adaptor(P&& p)
+ : detail::callable_base<Projection>(BOOST_HOF_FORWARD(P)(p))
+ {}
+
+ BOOST_HOF_RETURNS_CLASS(proj_adaptor);
+
+ template<class... Ts, class=detail::holder<decltype(std::declval<Projection>()(std::declval<Ts>()))...>>
+ constexpr BOOST_HOF_BY_VOID_RETURN operator()(Ts&&... xs) const
+ {
+#if BOOST_HOF_NO_ORDERED_BRACE_INIT
+ return boost::hof::detail::by_void_eval(this->base_projection(xs...), BOOST_HOF_FORWARD(Ts)(xs)...);
+#else
+#if BOOST_HOF_NO_CONSTEXPR_VOID
+ return
+#endif
+ boost::hof::detail::swallow{
+ (this->base_projection(xs...)(BOOST_HOF_FORWARD(Ts)(xs)), 0)...
+ };
+#endif
+ }
+};
+
+BOOST_HOF_DECLARE_STATIC_VAR(proj, detail::make<proj_adaptor>);
+
+}} // namespace boost::hof
+#endif
diff --git a/boost/hof/protect.hpp b/boost/hof/protect.hpp
new file mode 100644
index 0000000000..78f99a23b5
--- /dev/null
+++ b/boost/hof/protect.hpp
@@ -0,0 +1,80 @@
+/*=============================================================================
+ Copyright (c) 2014 Paul Fultz II
+ protect.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FUNCTION_PROTECT_H
+#define BOOST_HOF_GUARD_FUNCTION_PROTECT_H
+
+/// protect
+/// =======
+///
+/// Description
+/// -----------
+///
+/// The `protect` function adaptor can be used to make a bind expression be
+/// treated as a normal function instead. Both `bind` and
+/// [`lazy`](/include/boost/hof/lazy) eargerly evaluates nested bind expressions.
+/// The `protect` adaptor masks the type so `bind` or
+/// [`lazy`](/include/boost/hof/lazy) no longer recognizes the function as bind
+/// expression and evaluates it.
+///
+/// Synopsis
+/// --------
+///
+/// template<class F>
+/// constexpr protect_adaptor<F> protect(F f);
+///
+/// Semantics
+/// ---------
+///
+/// assert(lazy(f)(protect(lazy(g)(_1)))() == f(lazy(g)(_1)))
+///
+/// Requirements
+/// ------------
+///
+/// F must be:
+///
+/// * [ConstInvocable](ConstInvocable)
+/// * MoveConstructible
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+/// using namespace boost::hof;
+///
+/// int main() {
+/// auto lazy_id = lazy(identity)(_1);
+/// auto lazy_apply = lazy(apply)(protect(lazy_id), _1);
+/// assert(lazy_apply(3) == 3);
+/// }
+///
+/// See Also
+/// --------
+///
+/// * [lazy](lazy)
+///
+
+#include <utility>
+#include <boost/hof/reveal.hpp>
+#include <boost/hof/detail/forward.hpp>
+#include <boost/hof/detail/make.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+
+namespace boost { namespace hof {
+
+template<class F>
+struct protect_adaptor : detail::callable_base<F>
+{
+ typedef protect_adaptor fit_rewritable1_tag;
+ BOOST_HOF_INHERIT_CONSTRUCTOR(protect_adaptor, detail::callable_base<F>)
+};
+
+BOOST_HOF_DECLARE_STATIC_VAR(protect, detail::make<protect_adaptor>);
+
+}} // namespace boost::hof
+#endif
diff --git a/boost/hof/repeat.hpp b/boost/hof/repeat.hpp
new file mode 100644
index 0000000000..e73e43ee06
--- /dev/null
+++ b/boost/hof/repeat.hpp
@@ -0,0 +1,162 @@
+/*=============================================================================
+ Copyright (c) 2015 Paul Fultz II
+ repeat.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_REPEAT_H
+#define BOOST_HOF_GUARD_REPEAT_H
+
+/// repeat
+/// ======
+///
+/// Description
+/// -----------
+///
+/// The `repeat` function decorator will repeatedly apply a function a given
+/// number of times.
+///
+///
+/// Synopsis
+/// --------
+///
+/// template<class Integral>
+/// constexpr auto repeat(Integral);
+///
+/// Semantics
+/// ---------
+///
+/// assert(repeat(std::integral_constant<int, 0>{})(f)(xs...) == f(xs...));
+/// assert(repeat(std::integral_constant<int, 1>{})(f)(xs...) == f(f(xs...)));
+/// assert(repeat(0)(f)(xs...) == f(xs...));
+/// assert(repeat(1)(f)(xs...) == f(f(xs...)));
+///
+/// Requirements
+/// ------------
+///
+/// Integral must be:
+///
+/// * Integral
+///
+/// Or:
+///
+/// * IntegralConstant
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+///
+/// struct increment
+/// {
+/// template<class T>
+/// constexpr T operator()(T x) const
+/// {
+/// return x + 1;
+/// }
+/// };
+///
+/// int main() {
+/// auto increment_by_5 = boost::hof::repeat(std::integral_constant<int, 5>())(increment());
+/// assert(increment_by_5(1) == 6);
+/// }
+///
+
+#include <boost/hof/always.hpp>
+#include <boost/hof/detail/delegate.hpp>
+#include <boost/hof/detail/result_of.hpp>
+#include <boost/hof/detail/move.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+#include <boost/hof/decorate.hpp>
+#include <boost/hof/first_of.hpp>
+#include <boost/hof/detail/recursive_constexpr_depth.hpp>
+
+namespace boost { namespace hof { namespace detail {
+
+template<int N>
+struct repeater
+{
+ template<class F, class... Ts>
+ constexpr BOOST_HOF_SFINAE_RESULT(repeater<N-1>, id_<const F&>, result_of<const F&, id_<Ts>...>)
+ operator()(const F& f, Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS
+ (
+ repeater<N-1>()(f, f(BOOST_HOF_FORWARD(Ts)(xs)...))
+ );
+};
+
+template<>
+struct repeater<0>
+{
+ template<class F, class T>
+ constexpr T operator()(const F&, T&& x) const
+ BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(T(x))
+ {
+ return x;
+ }
+};
+
+struct repeat_constant_decorator
+{
+ template<class Integral, class F, class... Ts>
+ constexpr auto operator()(Integral, const F& f, Ts&&... xs) const BOOST_HOF_RETURNS
+ (
+ detail::repeater<Integral::type::value>()
+ (
+ f,
+ BOOST_HOF_FORWARD(Ts)(xs)...
+ )
+ );
+};
+
+template<int Depth>
+struct repeat_integral_decorator
+{
+ template<class Integral, class F, class T, class... Ts, class Self=repeat_integral_decorator<Depth-1>>
+ constexpr auto operator()(Integral n, const F& f, T&& x, Ts&&... xs) const BOOST_HOF_RETURNS
+ (
+ (n) ?
+ Self()(n-1, f, f(BOOST_HOF_FORWARD(T)(x), BOOST_HOF_FORWARD(Ts)(xs)...)) :
+ BOOST_HOF_FORWARD(T)(x)
+ );
+};
+
+template<>
+struct repeat_integral_decorator<0>
+{
+ template<class Integral, class F, class T, class Self=repeat_integral_decorator<0>>
+#if BOOST_HOF_HAS_RELAXED_CONSTEXPR
+ constexpr
+#endif
+ auto operator()(Integral n, const F& f, T x) const
+ BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT((n--, f(BOOST_HOF_FORWARD(T)(x))))
+ -> decltype(f(BOOST_HOF_FORWARD(T)(x)))
+ {
+ while(n > 0)
+ {
+ n--;
+ x = f(BOOST_HOF_FORWARD(T)(x));
+ }
+ return x;
+ }
+ // TODO: Add overload for lvalue
+};
+
+}
+
+#if BOOST_HOF_HAS_RELAXED_CONSTEXPR
+#define BOOST_HOF_REPEAT_CONSTEXPR_DEPTH 1
+#else
+#define BOOST_HOF_REPEAT_CONSTEXPR_DEPTH BOOST_HOF_RECURSIVE_CONSTEXPR_DEPTH
+#endif
+
+BOOST_HOF_DECLARE_STATIC_VAR(repeat, decorate_adaptor<
+ boost::hof::first_of_adaptor<
+ detail::repeat_constant_decorator,
+ detail::repeat_integral_decorator<BOOST_HOF_REPEAT_CONSTEXPR_DEPTH>
+>>);
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/repeat_while.hpp b/boost/hof/repeat_while.hpp
new file mode 100644
index 0000000000..f306b77132
--- /dev/null
+++ b/boost/hof/repeat_while.hpp
@@ -0,0 +1,181 @@
+/*=============================================================================
+ Copyright (c) 2015 Paul Fultz II
+ repeat_while.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_REPEAT_WHILE_H
+#define BOOST_HOF_GUARD_REPEAT_WHILE_H
+
+/// repeat_while
+/// ======
+///
+/// Description
+/// -----------
+///
+/// The `repeat_while` function decorator will repeatedly apply a function while
+/// the predicate returns a boolean that is true. If the predicate returns an
+/// `IntergralConstant` then the predicate is only evaluated at compile-time.
+///
+///
+/// Synopsis
+/// --------
+///
+/// template<class Predicate>
+/// constexpr auto repeat_while(Predicate predicate);
+///
+/// Requirements
+/// ------------
+///
+/// Predicate must be:
+///
+/// * [ConstFunctionObject](ConstFunctionObject)
+/// * MoveConstructible
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+///
+/// struct increment
+/// {
+/// template<class T>
+/// constexpr std::integral_constant<int, T::value + 1> operator()(T) const
+/// {
+/// return std::integral_constant<int, T::value + 1>();
+/// }
+/// };
+///
+/// struct not_6
+/// {
+/// template<class T>
+/// constexpr std::integral_constant<bool, (T::value != 6)>
+/// operator()(T) const
+/// {
+/// return std::integral_constant<bool, (T::value != 6)>();
+/// }
+/// };
+///
+/// typedef std::integral_constant<int, 1> one;
+/// typedef std::integral_constant<int, 6> six;
+///
+/// int main() {
+/// auto increment_until_6 = boost::hof::repeat_while(not_6())(increment());
+/// static_assert(std::is_same<six, decltype(increment_until_6(one()))>::value, "Error");
+/// }
+///
+
+#include <boost/hof/always.hpp>
+#include <boost/hof/detail/delegate.hpp>
+#include <boost/hof/detail/result_of.hpp>
+#include <boost/hof/detail/move.hpp>
+#include <boost/hof/decorate.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+#include <boost/hof/first_of.hpp>
+#include <boost/hof/detail/recursive_constexpr_depth.hpp>
+
+namespace boost { namespace hof { namespace detail {
+
+template<class P, class... Ts>
+struct compute_predicate
+{
+ typedef decltype(std::declval<P>()(std::declval<Ts>()...)) type;
+};
+
+template<bool B>
+struct while_repeater
+{
+ template<class F, class P, class... Ts>
+ constexpr BOOST_HOF_SFINAE_RESULT(while_repeater<
+ compute_predicate<P, typename result_of<const F&, id_<Ts>...>::type>::type::value
+ >, id_<const F&>, id_<const P&>, result_of<const F&, id_<Ts>...>)
+ operator()(const F& f, const P& p, Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS
+ (
+ while_repeater<
+ compute_predicate<P, decltype(f(BOOST_HOF_FORWARD(Ts)(xs)...))>::type::value
+ >()(f, p, f(BOOST_HOF_FORWARD(Ts)(xs)...))
+ );
+};
+
+template<>
+struct while_repeater<false>
+{
+ template<class F, class P, class T>
+ constexpr T operator()(const F&, const P&, T&& x) const
+ BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(x)
+ {
+ return x;
+ }
+};
+
+struct repeat_while_constant_decorator
+{
+ template<class P, class F, class... Ts>
+ constexpr auto operator()(const P& p, const F& f, Ts&&... xs) const BOOST_HOF_RETURNS
+ (
+ detail::while_repeater<
+ detail::compute_predicate<P, decltype(std::declval<F>()(BOOST_HOF_FORWARD(Ts)(xs)...))>::type::value
+ >()
+ (
+ f,
+ p,
+ BOOST_HOF_FORWARD(Ts)(xs)...
+ )
+ );
+};
+
+template<int Depth>
+struct repeat_while_integral_decorator
+{
+ template<class P, class F, class T, class... Ts, class Self=repeat_while_integral_decorator<Depth-1>>
+ constexpr auto operator()(const P& p, const F& f, T&& x, Ts&&... xs) const BOOST_HOF_RETURNS
+ (
+ (p(x, BOOST_HOF_FORWARD(Ts)(xs)...)) ?
+ Self()(
+ p,
+ f,
+ f(x, BOOST_HOF_FORWARD(Ts)(xs)...)
+ ) :
+ BOOST_HOF_FORWARD(T)(x)
+ );
+};
+
+template<>
+struct repeat_while_integral_decorator<0>
+{
+ template<class P, class F, class T, class Self=repeat_while_integral_decorator<0>>
+#if BOOST_HOF_HAS_RELAXED_CONSTEXPR
+ constexpr
+#endif
+ auto operator()(const P& p, const F& f, T x) const
+ BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT((p(x), f(x)))
+ -> decltype(f(x))
+ {
+ while(p(x))
+ {
+ // TODO: Should move?
+ x = f(x);
+ }
+ return x;
+ }
+};
+}
+
+#if BOOST_HOF_HAS_RELAXED_CONSTEXPR
+#define BOOST_HOF_REPEAT_WHILE_CONSTEXPR_DEPTH 1
+#else
+#define BOOST_HOF_REPEAT_WHILE_CONSTEXPR_DEPTH BOOST_HOF_RECURSIVE_CONSTEXPR_DEPTH
+#endif
+
+BOOST_HOF_DECLARE_STATIC_VAR(repeat_while, decorate_adaptor<
+ boost::hof::first_of_adaptor<
+ detail::repeat_while_constant_decorator,
+ detail::repeat_while_integral_decorator<BOOST_HOF_REPEAT_WHILE_CONSTEXPR_DEPTH>
+ >
+>);
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/result.hpp b/boost/hof/result.hpp
new file mode 100644
index 0000000000..e2c1d93dae
--- /dev/null
+++ b/boost/hof/result.hpp
@@ -0,0 +1,135 @@
+/*=============================================================================
+ Copyright (c) 2014 Paul Fultz II
+ result.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_RESULT_H
+#define BOOST_HOF_GUARD_RESULT_H
+
+/// result
+/// ======
+///
+/// Description
+/// -----------
+///
+/// The `result` function adaptor sets the return type for the function, which
+/// can be useful when dealing with multiple overloads. Since the return type
+/// is no longer dependent on the parameters passed to the function, the
+/// `result_adaptor` provides a nested `result_type` that is the return type
+/// of the function.
+///
+/// Synopsis
+/// --------
+///
+/// template<class Result, class F>
+/// constexpr result_adaptor<Result, F> result(F f);
+///
+/// Requirements
+/// ------------
+///
+/// F must be:
+///
+/// * [ConstInvocable](ConstInvocable)
+/// * MoveConstructible
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+///
+/// struct id
+/// {
+/// template<class T>
+/// T operator()(T x) const
+/// {
+/// return x;
+/// }
+/// };
+///
+/// int main() {
+/// auto int_result = boost::hof::result<int>(id());
+/// static_assert(std::is_same<decltype(int_result(true)), int>::value, "Not the same type");
+/// }
+///
+
+#include <boost/hof/detail/callable_base.hpp>
+#include <boost/hof/is_invocable.hpp>
+#include <boost/hof/always.hpp>
+#include <boost/hof/reveal.hpp>
+
+namespace boost { namespace hof {
+
+template<class Result, class F>
+struct result_adaptor : detail::callable_base<F>
+{
+ BOOST_HOF_INHERIT_CONSTRUCTOR(result_adaptor, detail::callable_base<F>)
+
+ typedef Result result_type;
+
+ struct failure
+ : failure_for<detail::callable_base<F>>
+ {};
+
+ template<class... Ts>
+ constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const
+ {
+ return boost::hof::always_ref(*this)(xs...);
+ }
+
+ template<class... Ts, class=typename std::enable_if<(boost::hof::is_invocable<F, Ts...>::value)>::type>
+ constexpr result_type operator()(Ts&&... xs) const
+ {
+ return this->base_function(xs...)(BOOST_HOF_FORWARD(Ts)(xs)...);
+ };
+};
+
+template<class F>
+struct result_adaptor<void, F> : detail::callable_base<F>
+{
+ BOOST_HOF_INHERIT_CONSTRUCTOR(result_adaptor, detail::callable_base<F>)
+
+ typedef void result_type;
+
+ template<class... Ts>
+ constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const
+ {
+ return boost::hof::always_ref(*this)(xs...);
+ }
+
+ template<class... Ts, class=typename std::enable_if<(boost::hof::is_invocable<F, Ts...>::value)>::type>
+ constexpr typename detail::holder<Ts...>::type operator()(Ts&&... xs) const
+ {
+ return (typename detail::holder<Ts...>::type)this->base_function(xs...)(BOOST_HOF_FORWARD(Ts)(xs)...);
+ };
+};
+
+#if BOOST_HOF_HAS_VARIABLE_TEMPLATES
+namespace result_detail {
+template<class Result>
+struct result_f
+{
+ template<class F>
+ constexpr result_adaptor<Result, F> operator()(F f) const
+ {
+ return result_adaptor<Result, F>(boost::hof::move(f));
+ }
+};
+
+}
+
+template<class Result>
+static constexpr auto result = result_detail::result_f<Result>{};
+#else
+template<class Result, class F>
+constexpr result_adaptor<Result, F> result(F f)
+{
+ return result_adaptor<Result, F>(boost::hof::move(f));
+}
+#endif
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/returns.hpp b/boost/hof/returns.hpp
new file mode 100644
index 0000000000..5360a38314
--- /dev/null
+++ b/boost/hof/returns.hpp
@@ -0,0 +1,249 @@
+/*=============================================================================
+ Copyright (c) 2014 Paul Fultz II
+ returns.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_RETURNS_H
+#define BOOST_HOF_GUARD_RETURNS_H
+
+/// BOOST_HOF_RETURNS
+/// ===========
+///
+/// Description
+/// -----------
+///
+/// The `BOOST_HOF_RETURNS` macro defines the function as the expression
+/// equivalence. It does this by deducing `noexcept` and the return type by
+/// using a trailing `decltype`. Instead of repeating the expression for the
+/// return type, `noexcept` clause and the function body, this macro will
+/// reduce the code duplication from that.
+///
+/// Note: The expression used to deduce the return the type will also
+/// constrain the template function and deduce `noexcept` as well, which is
+/// different behaviour than using C++14's return type deduction.
+///
+/// Synopsis
+/// --------
+///
+/// #define BOOST_HOF_RETURNS(...)
+///
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+///
+/// template<class T, class U>
+/// auto sum(T x, U y) BOOST_HOF_RETURNS(x+y);
+///
+/// int main() {
+/// assert(3 == sum(1, 2));
+/// }
+///
+///
+/// Incomplete this
+/// ---------------
+///
+/// Description
+/// -----------
+///
+/// On some non-conformant compilers, such as gcc, the `this` variable cannot
+/// be used inside the `BOOST_HOF_RETURNS` macro because it is considered an
+/// incomplete type. So the following macros are provided to help workaround
+/// the issue.
+///
+///
+/// Synopsis
+/// --------
+///
+/// // Declares the type of the `this` variable
+/// #define BOOST_HOF_RETURNS_CLASS(...)
+/// // Used to refer to the `this` variable in the BOOST_HOF_RETURNS macro
+/// #define BOOST_HOF_THIS
+/// // Used to refer to the const `this` variable in the BOOST_HOF_RETURNS macro
+/// #define BOOST_HOF_CONST_THIS
+///
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+///
+/// struct add_1
+/// {
+/// int a;
+/// add_1() : a(1) {}
+///
+/// BOOST_HOF_RETURNS_CLASS(add_1);
+///
+/// template<class T>
+/// auto operator()(T x) const
+/// BOOST_HOF_RETURNS(x+BOOST_HOF_CONST_THIS->a);
+/// };
+///
+/// int main() {
+/// assert(3 == add_1()(2));
+/// }
+///
+///
+/// Mangling overloads
+/// ------------------
+///
+/// Description
+/// -----------
+///
+/// On older compilers some operations done in the expressions cannot be
+/// properly mangled. These macros help provide workarounds for these
+/// operations on older compilers.
+///
+///
+/// Synopsis
+/// --------
+///
+/// // Explicitly defines the type for name mangling
+/// #define BOOST_HOF_MANGLE_CAST(...)
+/// // C cast for name mangling
+/// #define BOOST_HOF_RETURNS_C_CAST(...)
+/// // Reinterpret cast for name mangling
+/// #define BOOST_HOF_RETURNS_REINTERPRET_CAST(...)
+/// // Static cast for name mangling
+/// #define BOOST_HOF_RETURNS_STATIC_CAST(...)
+/// // Construction for name mangling
+/// #define BOOST_HOF_RETURNS_CONSTRUCT(...)
+///
+
+
+#include <boost/hof/config.hpp>
+#include <utility>
+#include <boost/hof/detail/forward.hpp>
+#include <boost/hof/detail/noexcept.hpp>
+
+#define BOOST_HOF_EAT(...)
+#define BOOST_HOF_REM(...) __VA_ARGS__
+
+#if BOOST_HOF_HAS_COMPLETE_DECLTYPE && BOOST_HOF_HAS_MANGLE_OVERLOAD
+#ifdef _MSC_VER
+// Since decltype can't be used in noexcept on MSVC, we can't check for noexcept
+// move constructors.
+#define BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(...) BOOST_HOF_NOEXCEPT(noexcept(__VA_ARGS__))
+#else
+#define BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(...) BOOST_HOF_NOEXCEPT(noexcept(static_cast<decltype(__VA_ARGS__)>(__VA_ARGS__)))
+#endif
+#define BOOST_HOF_RETURNS(...) \
+BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(__VA_ARGS__) \
+-> decltype(__VA_ARGS__) { return __VA_ARGS__; }
+#define BOOST_HOF_THIS this
+#define BOOST_HOF_CONST_THIS this
+#define BOOST_HOF_RETURNS_CLASS(...) \
+void fit_returns_class_check() \
+{ \
+ static_assert(std::is_same<__VA_ARGS__*, decltype(this)>::value, \
+ "Returns class " #__VA_ARGS__ " type doesn't match"); \
+}
+
+#define BOOST_HOF_MANGLE_CAST(...) BOOST_HOF_REM
+
+#define BOOST_HOF_RETURNS_C_CAST(...) (__VA_ARGS__) BOOST_HOF_REM
+#define BOOST_HOF_RETURNS_REINTERPRET_CAST(...) reinterpret_cast<__VA_ARGS__>
+#define BOOST_HOF_RETURNS_STATIC_CAST(...) static_cast<__VA_ARGS__>
+#define BOOST_HOF_RETURNS_CONSTRUCT(...) __VA_ARGS__
+#else
+#include <boost/hof/detail/pp.hpp>
+
+#define BOOST_HOF_RETURNS_RETURN(...) return BOOST_HOF_RETURNS_RETURN_X(BOOST_HOF_PP_WALL(__VA_ARGS__))
+#define BOOST_HOF_RETURNS_RETURN_X(...) __VA_ARGS__
+
+#ifdef _MSC_VER
+// Since decltype can't be used in noexcept on MSVC, we can't check for noexcept
+// move constructors.
+#define BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(...) BOOST_HOF_NOEXCEPT(noexcept(BOOST_HOF_RETURNS_DECLTYPE_CONTEXT(__VA_ARGS__)))
+#else
+#define BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(...) BOOST_HOF_NOEXCEPT(noexcept(static_cast<decltype(BOOST_HOF_RETURNS_DECLTYPE_CONTEXT(__VA_ARGS__))>(BOOST_HOF_RETURNS_DECLTYPE_CONTEXT(__VA_ARGS__))))
+#endif
+
+#define BOOST_HOF_RETURNS_DECLTYPE(...) \
+-> decltype(BOOST_HOF_RETURNS_DECLTYPE_CONTEXT(__VA_ARGS__))
+
+#define BOOST_HOF_RETURNS_DECLTYPE_CONTEXT(...) BOOST_HOF_RETURNS_DECLTYPE_CONTEXT_X(BOOST_HOF_PP_WALL(__VA_ARGS__))
+#define BOOST_HOF_RETURNS_DECLTYPE_CONTEXT_X(...) __VA_ARGS__
+
+#define BOOST_HOF_RETURNS_THAT(...) BOOST_HOF_PP_IIF(BOOST_HOF_PP_IS_PAREN(BOOST_HOF_RETURNS_DECLTYPE_CONTEXT(())))(\
+ (boost::hof::detail::check_this<__VA_ARGS__, decltype(this)>(), this), \
+ std::declval<__VA_ARGS__>() \
+)
+
+#define BOOST_HOF_THIS BOOST_HOF_PP_RAIL(BOOST_HOF_RETURNS_THAT)(fit_this_type)
+#define BOOST_HOF_CONST_THIS BOOST_HOF_PP_RAIL(BOOST_HOF_RETURNS_THAT)(fit_const_this_type)
+
+#define BOOST_HOF_RETURNS_CLASS(...) typedef __VA_ARGS__* fit_this_type; typedef const __VA_ARGS__* fit_const_this_type
+
+#define BOOST_HOF_RETURNS(...) \
+BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(__VA_ARGS__) \
+BOOST_HOF_RETURNS_DECLTYPE(__VA_ARGS__) \
+{ BOOST_HOF_RETURNS_RETURN(__VA_ARGS__); }
+
+
+namespace boost { namespace hof { namespace detail {
+template<class Assumed, class T>
+struct check_this
+{
+ static_assert(std::is_same<T, Assumed>::value, "Incorret BOOST_HOF_THIS or BOOST_HOF_CONST_THIS used.");
+};
+
+}}} // namespace boost::hof
+
+#endif
+
+
+#if BOOST_HOF_HAS_MANGLE_OVERLOAD
+
+#define BOOST_HOF_MANGLE_CAST(...) BOOST_HOF_REM
+
+#define BOOST_HOF_RETURNS_C_CAST(...) (__VA_ARGS__) BOOST_HOF_REM
+#define BOOST_HOF_RETURNS_REINTERPRET_CAST(...) reinterpret_cast<__VA_ARGS__>
+#define BOOST_HOF_RETURNS_STATIC_CAST(...) static_cast<__VA_ARGS__>
+#define BOOST_HOF_RETURNS_CONSTRUCT(...) __VA_ARGS__
+
+#else
+
+#define BOOST_HOF_RETURNS_DERAIL_MANGLE_CAST(...) BOOST_HOF_PP_IIF(BOOST_HOF_PP_IS_PAREN(BOOST_HOF_RETURNS_DECLTYPE_CONTEXT(())))(\
+ BOOST_HOF_REM, \
+ std::declval<__VA_ARGS__>() BOOST_HOF_EAT \
+)
+#define BOOST_HOF_MANGLE_CAST BOOST_HOF_PP_RAIL(BOOST_HOF_RETURNS_DERAIL_MANGLE_CAST)
+
+
+#define BOOST_HOF_RETURNS_DERAIL_C_CAST(...) BOOST_HOF_PP_IIF(BOOST_HOF_PP_IS_PAREN(BOOST_HOF_RETURNS_DECLTYPE_CONTEXT(())))(\
+ (__VA_ARGS__) BOOST_HOF_REM, \
+ std::declval<__VA_ARGS__>() BOOST_HOF_EAT \
+)
+#define BOOST_HOF_RETURNS_C_CAST BOOST_HOF_PP_RAIL(BOOST_HOF_RETURNS_DERAIL_C_CAST)
+
+
+#define BOOST_HOF_RETURNS_DERAIL_REINTERPRET_CAST(...) BOOST_HOF_PP_IIF(BOOST_HOF_PP_IS_PAREN(BOOST_HOF_RETURNS_DECLTYPE_CONTEXT(())))(\
+ reinterpret_cast<__VA_ARGS__>, \
+ std::declval<__VA_ARGS__>() BOOST_HOF_EAT \
+)
+#define BOOST_HOF_RETURNS_REINTERPRET_CAST BOOST_HOF_PP_RAIL(BOOST_HOF_RETURNS_DERAIL_REINTERPRET_CAST)
+
+#define BOOST_HOF_RETURNS_DERAIL_STATIC_CAST(...) BOOST_HOF_PP_IIF(BOOST_HOF_PP_IS_PAREN(BOOST_HOF_RETURNS_DECLTYPE_CONTEXT(())))(\
+ static_cast<__VA_ARGS__>, \
+ std::declval<__VA_ARGS__>() BOOST_HOF_EAT \
+)
+#define BOOST_HOF_RETURNS_STATIC_CAST BOOST_HOF_PP_RAIL(BOOST_HOF_RETURNS_DERAIL_STATIC_CAST)
+
+#define BOOST_HOF_RETURNS_DERAIL_CONSTRUCT(...) BOOST_HOF_PP_IIF(BOOST_HOF_PP_IS_PAREN(BOOST_HOF_RETURNS_DECLTYPE_CONTEXT(())))(\
+ __VA_ARGS__, \
+ std::declval<__VA_ARGS__>() BOOST_HOF_EAT \
+)
+#define BOOST_HOF_RETURNS_CONSTRUCT BOOST_HOF_PP_RAIL(BOOST_HOF_RETURNS_DERAIL_CONSTRUCT)
+
+#endif
+
+#define BOOST_HOF_AUTO_FORWARD(...) BOOST_HOF_RETURNS_STATIC_CAST(decltype(__VA_ARGS__))(__VA_ARGS__)
+
+#endif
diff --git a/boost/hof/reveal.hpp b/boost/hof/reveal.hpp
new file mode 100644
index 0000000000..d8972b08cb
--- /dev/null
+++ b/boost/hof/reveal.hpp
@@ -0,0 +1,385 @@
+/*=============================================================================
+ Copyright (c) 2014 Paul Fultz II
+ reveal.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FUNCTION_REVEAL_H
+#define BOOST_HOF_GUARD_FUNCTION_REVEAL_H
+
+/// reveal
+/// ======
+///
+/// Description
+/// -----------
+///
+/// The `reveal` function adaptor helps shows the error messages that get
+/// masked on some compilers. Sometimes an error in a function that causes a
+/// substitution failure, will remove the function from valid overloads. On
+/// compilers without a backtrace for substitution failure, this will mask the
+/// error inside the function. The `reveal` adaptor will expose these error
+/// messages while still keeping the function SFINAE-friendly.
+///
+/// Sample
+/// ------
+///
+/// If we take the `print` example from the quick start guide like this:
+///
+/// namespace adl {
+///
+/// using std::begin;
+///
+/// template<class R>
+/// auto adl_begin(R&& r) BOOST_HOF_RETURNS(begin(r));
+/// }
+///
+/// BOOST_HOF_STATIC_LAMBDA_FUNCTION(for_each_tuple) = [](const auto& sequence, auto f) BOOST_HOF_RETURNS
+/// (
+/// boost::hof::unpack(boost::hof::proj(f))(sequence)
+/// );
+///
+/// auto print = boost::hof::fix(boost::hof::first_of(
+/// [](auto, const auto& x) -> decltype(std::cout << x, void())
+/// {
+/// std::cout << x << std::endl;
+/// },
+/// [](auto self, const auto& range) -> decltype(self(*adl::adl_begin(range)), void())
+/// {
+/// for(const auto& x:range) self(x);
+/// },
+/// [](auto self, const auto& tuple) -> decltype(for_each_tuple(tuple, self), void())
+/// {
+/// return for_each_tuple(tuple, self);
+/// }
+/// ));
+///
+/// Which prints numbers and vectors:
+///
+/// print(5);
+///
+/// std::vector<int> v = { 1, 2, 3, 4 };
+/// print(v);
+///
+/// However, if we pass a type that can't be printed, we get an error like
+/// this:
+///
+/// print.cpp:49:5: error: no matching function for call to object of type 'boost::hof::fix_adaptor<boost::hof::first_of_adaptor<(lambda at print.cpp:29:9), (lambda at print.cpp:33:9), (lambda at print.cpp:37:9)> >'
+/// print(foo{});
+/// ^~~~~
+/// fix.hpp:158:5: note: candidate template ignored: substitution failure [with Ts = <foo>]: no matching function for call to object of type 'const boost::hof::first_of_adaptor<(lambda at
+/// print.cpp:29:9), (lambda at print.cpp:33:9), (lambda at print.cpp:37:9)>'
+/// operator()(Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS
+///
+/// Which is short and gives very little information why it can't be called.
+/// It doesn't even show the overloads that were try. However, using the
+/// `reveal` adaptor we can get more info about the error like this:
+///
+/// print.cpp:49:5: error: no matching function for call to object of type 'boost::hof::reveal_adaptor<boost::hof::fix_adaptor<boost::hof::first_of_adaptor<(lambda at print.cpp:29:9), (lambda at print.cpp:33:9),
+/// (lambda at print.cpp:37:9)> >, boost::hof::fix_adaptor<boost::hof::first_of_adaptor<(lambda at print.cpp:29:9), (lambda at print.cpp:33:9), (lambda at print.cpp:37:9)> > >'
+/// boost::hof::reveal(print)(foo{});
+/// ^~~~~~~~~~~~~~~~~~
+/// reveal.hpp:149:20: note: candidate template ignored: substitution failure [with Ts = <foo>, $1 = void]: no matching function for call to object of type '(lambda at print.cpp:29:9)'
+/// constexpr auto operator()(Ts&&... xs) const
+/// ^
+/// reveal.hpp:149:20: note: candidate template ignored: substitution failure [with Ts = <foo>, $1 = void]: no matching function for call to object of type '(lambda at print.cpp:33:9)'
+/// constexpr auto operator()(Ts&&... xs) const
+/// ^
+/// reveal.hpp:149:20: note: candidate template ignored: substitution failure [with Ts = <foo>, $1 = void]: no matching function for call to object of type '(lambda at print.cpp:37:9)'
+/// constexpr auto operator()(Ts&&... xs) const
+/// ^
+/// fix.hpp:158:5: note: candidate template ignored: substitution failure [with Ts = <foo>]: no matching function for call to object of type 'const boost::hof::first_of_adaptor<(lambda at
+/// print.cpp:29:9), (lambda at print.cpp:33:9), (lambda at print.cpp:37:9)>'
+/// operator()(Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS
+///
+/// So now the error has a note for each of the lambda overloads it tried. Of
+/// course this can be improved even further by providing custom reporting of
+/// failures.
+///
+/// Synopsis
+/// --------
+///
+/// template<class F>
+/// reveal_adaptor<F> reveal(F f);
+///
+/// Requirements
+/// ------------
+///
+/// F must be:
+///
+/// * [ConstInvocable](ConstInvocable)
+/// * MoveConstructible
+///
+/// Reporting Failures
+/// ------------------
+///
+/// By default, `reveal` reports the substitution failure by trying to call
+/// the function. However, more detail expressions can be be reported from a
+/// template alias by using `as_failure`. This is done by defining a nested
+/// `failure` struct in the function object and then inheriting from
+/// `as_failure`. Also multiple failures can be reported by using
+/// `with_failures`.
+///
+/// Synopsis
+/// --------
+///
+/// // Report failure by instantiating the Template
+/// template<template<class...> class Template>
+/// struct as_failure;
+///
+/// // Report multiple falures
+/// template<class... Failures>
+/// struct with_failures;
+///
+/// // Report the failure for each function
+/// template<class... Fs>
+/// struct failure_for;
+///
+/// // Get the failure of a function
+/// template<class F>
+/// struct get_failure;
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+///
+/// struct sum_f
+/// {
+/// template<class T, class U>
+/// using sum_failure = decltype(std::declval<T>()+std::declval<U>());
+///
+/// struct failure
+/// : boost::hof::as_failure<sum_failure>
+/// {};
+///
+/// template<class T, class U>
+/// auto operator()(T x, U y) const BOOST_HOF_RETURNS(x+y);
+/// };
+///
+/// int main() {
+/// assert(sum_f()(1, 2) == 3);
+/// }
+///
+
+#include <boost/hof/always.hpp>
+#include <boost/hof/returns.hpp>
+#include <boost/hof/is_invocable.hpp>
+#include <boost/hof/identity.hpp>
+#include <boost/hof/detail/move.hpp>
+#include <boost/hof/detail/callable_base.hpp>
+#include <boost/hof/detail/delegate.hpp>
+#include <boost/hof/detail/holder.hpp>
+#include <boost/hof/detail/join.hpp>
+#include <boost/hof/detail/make.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+#include <boost/hof/detail/using.hpp>
+
+#ifndef BOOST_HOF_REVEAL_USE_TEMPLATE_ALIAS
+#ifdef __clang__
+#define BOOST_HOF_REVEAL_USE_TEMPLATE_ALIAS 1
+#else
+#define BOOST_HOF_REVEAL_USE_TEMPLATE_ALIAS 0
+#endif
+#endif
+
+namespace boost { namespace hof {
+
+namespace detail {
+
+
+template<class T, class=void>
+struct has_failure
+: std::false_type
+{};
+
+template<class T>
+struct has_failure<T, typename holder<
+ typename T::failure
+>::type>
+: std::true_type
+{};
+
+struct identity_failure
+{
+ template<class T>
+ T operator()(T&& x);
+
+ template<class T>
+ static T&& val();
+#if BOOST_HOF_REVEAL_USE_TEMPLATE_ALIAS
+ template<template<class...> class Template, class... Ts>
+ BOOST_HOF_USING(defer, Template<Ts...>);
+#else
+ template<template<class...> class Template, class... Ts>
+ static auto defer(Ts&&...) -> Template<Ts...>;
+#endif
+
+};
+
+}
+
+template<class F, class=void>
+struct get_failure
+{
+ template<class... Ts>
+ struct of
+ {
+#if BOOST_HOF_REVEAL_USE_TEMPLATE_ALIAS
+ template<class Id>
+ using apply = decltype(Id()(std::declval<F>())(std::declval<Ts>()...));
+#else
+ template<class Id>
+ static auto apply(Id id) -> decltype(id(std::declval<F>())(std::declval<Ts>()...));
+#endif
+ };
+};
+
+template<class F>
+struct get_failure<F, typename std::enable_if<detail::has_failure<F>::value>::type>
+: F::failure
+{};
+
+template<template<class...> class Template>
+struct as_failure
+{
+ template<class... Ts>
+ struct of
+ {
+#if BOOST_HOF_REVEAL_USE_TEMPLATE_ALIAS
+ template<class Id>
+ using apply = typename Id::template defer<Template, Ts...>;
+#else
+ template<class Id>
+ static auto apply(Id) -> decltype(Id::template defer<Template, Ts...>());
+#endif
+ };
+};
+
+namespace detail {
+template<class Failure, class... Ts>
+BOOST_HOF_USING_TYPENAME(apply_failure, Failure::template of<Ts...>);
+
+template<class F, class Failure>
+struct reveal_failure
+{
+ // Add default constructor to make clang 3.4 happy
+ constexpr reveal_failure()
+ {}
+ // This is just a placeholder to produce a note in the compiler, it is
+ // never called
+ template<
+ class... Ts,
+ class=typename std::enable_if<(!is_invocable<F, Ts...>::value)>::type
+ >
+ constexpr auto operator()(Ts&&... xs) const
+#if BOOST_HOF_REVEAL_USE_TEMPLATE_ALIAS
+ -> typename apply_failure<Failure, Ts...>::template apply<boost::hof::detail::identity_failure>;
+#else
+ -> decltype(apply_failure<Failure, Ts...>::apply(boost::hof::detail::identity_failure()));
+#endif
+};
+
+template<class F, class Failure=get_failure<F>, class=void>
+struct traverse_failure
+: reveal_failure<F, Failure>
+{
+ constexpr traverse_failure()
+ {}
+};
+
+template<class F, class Failure>
+struct traverse_failure<F, Failure, typename holder<
+ typename Failure::children
+>::type>
+: Failure::children::template overloads<F>
+{
+ constexpr traverse_failure()
+ {}
+};
+
+template<class Failure, class Transform, class=void>
+struct transform_failures
+: Transform::template apply<Failure>
+{};
+
+template<class Failure, class Transform>
+struct transform_failures<Failure, Transform, typename holder<
+ typename Failure::children
+>::type>
+: Failure::children::template transform<Transform>
+{};
+
+}
+
+template<class Failure, class... Failures>
+struct failures;
+
+template<class... Fs>
+struct with_failures
+{
+ typedef BOOST_HOF_JOIN(failures, Fs...) children;
+};
+
+template<class Failure, class... Failures>
+struct failures
+{
+ template<class Transform>
+ BOOST_HOF_USING(transform, with_failures<detail::transform_failures<Failure, Transform>, detail::transform_failures<Failures, Transform>...>);
+
+ template<class F, class FailureBase=BOOST_HOF_JOIN(failures, Failures...)>
+ struct overloads
+ : detail::traverse_failure<F, Failure>, FailureBase::template overloads<F>
+ {
+ constexpr overloads()
+ {}
+ using detail::traverse_failure<F, Failure>::operator();
+ using FailureBase::template overloads<F>::operator();
+ };
+};
+
+template<class Failure>
+struct failures<Failure>
+{
+ template<class Transform>
+ BOOST_HOF_USING(transform, with_failures<detail::transform_failures<Failure, Transform>>);
+
+ template<class F>
+ BOOST_HOF_USING(overloads, detail::traverse_failure<F, Failure>);
+};
+
+template<class Transform, class... Fs>
+struct failure_map
+: with_failures<detail::transform_failures<get_failure<Fs>, Transform>...>
+{};
+
+template<class... Fs>
+struct failure_for
+: with_failures<get_failure<Fs>...>
+{};
+
+template<class F, class Base=detail::callable_base<F>>
+struct reveal_adaptor
+: detail::traverse_failure<Base>, Base
+{
+ typedef reveal_adaptor fit_rewritable1_tag;
+ using detail::traverse_failure<Base>::operator();
+ using Base::operator();
+
+ BOOST_HOF_INHERIT_CONSTRUCTOR(reveal_adaptor, Base);
+};
+// Avoid double reveals, it causes problem on gcc 4.6
+template<class F>
+struct reveal_adaptor<reveal_adaptor<F>>
+: reveal_adaptor<F>
+{
+ typedef reveal_adaptor fit_rewritable1_tag;
+ BOOST_HOF_INHERIT_CONSTRUCTOR(reveal_adaptor, reveal_adaptor<F>);
+};
+
+BOOST_HOF_DECLARE_STATIC_VAR(reveal, detail::make<reveal_adaptor>);
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/reverse_fold.hpp b/boost/hof/reverse_fold.hpp
new file mode 100644
index 0000000000..771cb95c41
--- /dev/null
+++ b/boost/hof/reverse_fold.hpp
@@ -0,0 +1,173 @@
+/*=============================================================================
+ Copyright (c) 2015 Paul Fultz II
+ reverse_fold.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_REVERSE_FOLD_H
+#define BOOST_HOF_GUARD_REVERSE_FOLD_H
+
+/// reverse_fold
+/// ========
+///
+/// Description
+/// -----------
+///
+/// The `reverse_fold` function adaptor uses a binary function to apply a
+/// reverse [fold]
+/// (https://en.wikipedia.org/wiki/Fold_%28higher-order_function%29)(ie right
+/// fold in functional programming terms) operation to the arguments passed to
+/// the function. Additionally, an optional initial state can be provided,
+/// otherwise the first argument is used as the initial state.
+///
+/// The arguments to the binary function, take first the state and then the
+/// argument.
+///
+/// Synopsis
+/// --------
+///
+/// template<class F, class State>
+/// constexpr reverse_fold_adaptor<F, State> reverse_fold(F f, State s);
+///
+/// template<class F>
+/// constexpr reverse_fold_adaptor<F> reverse_fold(F f);
+///
+/// Semantics
+/// ---------
+///
+/// assert(reverse_fold(f, z)() == z);
+/// assert(reverse_fold(f, z)(x, xs...) == f(reverse_fold(f, z)(xs...), x));
+/// assert(reverse_fold(f)(x) == x);
+/// assert(reverse_fold(f)(x, xs...) == f(reverse_fold(f)(xs...), x));
+///
+/// Requirements
+/// ------------
+///
+/// State must be:
+///
+/// * CopyConstructible
+///
+/// F must be:
+///
+/// * [BinaryInvocable](BinaryInvocable)
+/// * MoveConstructible
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+///
+/// struct max_f
+/// {
+/// template<class T, class U>
+/// constexpr T operator()(T x, U y) const
+/// {
+/// return x > y ? x : y;
+/// }
+/// };
+///
+/// int main() {
+/// assert(boost::hof::reverse_fold(max_f())(2, 3, 4, 5) == 5);
+/// }
+///
+/// References
+/// ----------
+///
+/// * [Projections](Projections)
+/// * [Variadic print](<Variadic print>)
+///
+
+#include <boost/hof/detail/callable_base.hpp>
+#include <boost/hof/detail/delegate.hpp>
+#include <boost/hof/detail/compressed_pair.hpp>
+#include <boost/hof/detail/move.hpp>
+#include <boost/hof/detail/make.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+
+namespace boost { namespace hof { namespace detail {
+
+struct v_reverse_fold
+{
+ BOOST_HOF_RETURNS_CLASS(v_reverse_fold);
+ template<class F, class State, class T, class... Ts>
+ constexpr BOOST_HOF_SFINAE_MANUAL_RESULT(const F&, result_of<const v_reverse_fold&, id_<const F&>, id_<State>, id_<Ts>...>, id_<T>)
+ operator()(const F& f, State&& state, T&& x, Ts&&... xs) const BOOST_HOF_SFINAE_MANUAL_RETURNS
+ (
+ f((*BOOST_HOF_CONST_THIS)(f, BOOST_HOF_FORWARD(State)(state), BOOST_HOF_FORWARD(Ts)(xs)...), BOOST_HOF_FORWARD(T)(x))
+ );
+
+ template<class F, class State>
+ constexpr State operator()(const F&, State&& state) const noexcept
+ {
+ return BOOST_HOF_FORWARD(State)(state);
+ }
+};
+
+}
+
+template<class F, class State=void>
+struct reverse_fold_adaptor
+: detail::compressed_pair<detail::callable_base<F>, State>
+{
+ typedef detail::compressed_pair<detail::callable_base<F>, State> base_type;
+ BOOST_HOF_INHERIT_CONSTRUCTOR(reverse_fold_adaptor, base_type)
+
+ template<class... Ts>
+ constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const noexcept
+ {
+ return this->first(xs...);
+ }
+
+ template<class... Ts>
+ constexpr State get_state(Ts&&... xs) const noexcept
+ {
+ return this->second(xs...);
+ }
+
+ BOOST_HOF_RETURNS_CLASS(reverse_fold_adaptor);
+
+ template<class... Ts>
+ constexpr BOOST_HOF_SFINAE_RESULT(detail::v_reverse_fold, id_<const detail::callable_base<F>&>, id_<State>, id_<Ts>...)
+ operator()(Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS
+ (
+ detail::v_reverse_fold()(
+ BOOST_HOF_MANGLE_CAST(const detail::callable_base<F>&)(BOOST_HOF_CONST_THIS->base_function(xs...)),
+ BOOST_HOF_MANGLE_CAST(State)(BOOST_HOF_CONST_THIS->get_state(xs...)),
+ BOOST_HOF_FORWARD(Ts)(xs)...
+ )
+ )
+};
+
+
+template<class F>
+struct reverse_fold_adaptor<F, void>
+: detail::callable_base<F>
+{
+ BOOST_HOF_INHERIT_CONSTRUCTOR(reverse_fold_adaptor, detail::callable_base<F>)
+
+ template<class... Ts>
+ constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const noexcept
+ {
+ return boost::hof::always_ref(*this)(xs...);
+ }
+
+ BOOST_HOF_RETURNS_CLASS(reverse_fold_adaptor);
+
+ template<class... Ts>
+ constexpr BOOST_HOF_SFINAE_RESULT(detail::v_reverse_fold, id_<const detail::callable_base<F>&>, id_<Ts>...)
+ operator()(Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS
+ (
+ detail::v_reverse_fold()(
+ BOOST_HOF_MANGLE_CAST(const detail::callable_base<F>&)(BOOST_HOF_CONST_THIS->base_function(xs...)),
+ BOOST_HOF_FORWARD(Ts)(xs)...
+ )
+ )
+};
+
+BOOST_HOF_DECLARE_STATIC_VAR(reverse_fold, detail::make<reverse_fold_adaptor>);
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/rotate.hpp b/boost/hof/rotate.hpp
new file mode 100644
index 0000000000..b288a06c47
--- /dev/null
+++ b/boost/hof/rotate.hpp
@@ -0,0 +1,101 @@
+/*=============================================================================
+ Copyright (c) 2015 Paul Fultz II
+ rotate.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_ROTATE_H
+#define BOOST_HOF_GUARD_ROTATE_H
+
+/// rotate
+/// ====
+///
+/// Description
+/// -----------
+///
+/// The `rotate` function adaptor moves the first parameter to the last
+/// parameter.
+///
+/// Synopsis
+/// --------
+///
+/// template<class F>
+/// rotate_adaptor<F> rotate(F f);
+///
+/// Semantics
+/// ---------
+///
+/// assert(rotate(f)(x, xs...) == f(xs..., x));
+///
+/// Requirements
+/// ------------
+///
+/// F must be:
+///
+/// * [ConstInvocable](ConstInvocable)
+/// * MoveConstructible
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+///
+/// int main() {
+/// int r = boost::hof::rotate(boost::hof::_ - boost::hof::_)(2, 5);
+/// assert(r == 3);
+/// }
+///
+
+#include <boost/hof/detail/result_of.hpp>
+#include <boost/hof/reveal.hpp>
+#include <boost/hof/detail/make.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+
+namespace boost { namespace hof {
+
+template<class F>
+struct rotate_adaptor : detail::callable_base<F>
+{
+ typedef rotate_adaptor fit_rewritable1_tag;
+ BOOST_HOF_INHERIT_CONSTRUCTOR(rotate_adaptor, detail::callable_base<F>);
+
+ template<class... Ts>
+ constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const noexcept
+ {
+ return boost::hof::always_ref(*this)(xs...);
+ }
+
+ struct rotate_failure
+ {
+ template<class Failure>
+ struct apply
+ {
+ template<class T, class... Ts>
+ struct of
+ : Failure::template of<Ts..., T>
+ {};
+ };
+ };
+
+ struct failure
+ : failure_map<rotate_failure, detail::callable_base<F>>
+ {};
+
+ BOOST_HOF_RETURNS_CLASS(rotate_adaptor);
+
+ template<class T, class... Ts>
+ constexpr BOOST_HOF_SFINAE_RESULT(const detail::callable_base<F>&, id_<Ts>..., id_<T>)
+ operator()(T&& x, Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS
+ (
+ (BOOST_HOF_MANGLE_CAST(const detail::callable_base<F>&)(BOOST_HOF_CONST_THIS->base_function(xs...)))
+ (BOOST_HOF_FORWARD(Ts)(xs)..., BOOST_HOF_FORWARD(T)(x))
+ );
+};
+
+BOOST_HOF_DECLARE_STATIC_VAR(rotate, detail::make<rotate_adaptor>);
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/static.hpp b/boost/hof/static.hpp
new file mode 100644
index 0000000000..2539d93de0
--- /dev/null
+++ b/boost/hof/static.hpp
@@ -0,0 +1,97 @@
+/*=============================================================================
+ Copyright (c) 2014 Paul Fultz II
+ static.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FUNCTION_STATIC_H
+#define BOOST_HOF_GUARD_FUNCTION_STATIC_H
+
+/// static
+/// ======
+///
+/// Description
+/// -----------
+///
+/// The `static_` adaptor is a static function adaptor that allows any
+/// default-constructible function object to be static-initialized. Functions
+/// initialized by `static_` cannot be used in `constexpr` functions. If the
+/// function needs to be statically initialized and called in a `constexpr`
+/// context, then a `constexpr` constructor needs to be used rather than
+/// `static_`.
+///
+/// Synopsis
+/// --------
+///
+/// template<class F>
+/// class static_;
+///
+/// Requirements
+/// ------------
+///
+/// F must be:
+///
+/// * [ConstFunctionObject](ConstFunctionObject)
+/// * DefaultConstructible
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+/// using namespace boost::hof;
+///
+/// // In C++ this class can't be static-initialized, because of the non-
+/// // trivial default constructor.
+/// struct times_function
+/// {
+/// double factor;
+/// times_function() : factor(2)
+/// {}
+/// template<class T>
+/// T operator()(T x) const
+/// {
+/// return x*factor;
+/// }
+/// };
+///
+/// static constexpr static_<times_function> times2 = {};
+///
+/// int main() {
+/// assert(6 == times2(3));
+/// }
+///
+
+#include <boost/hof/detail/result_of.hpp>
+#include <boost/hof/reveal.hpp>
+
+namespace boost { namespace hof {
+
+template<class F>
+struct static_
+{
+
+ struct failure
+ : failure_for<F>
+ {};
+
+ const F& base_function() const
+ BOOST_HOF_NOEXCEPT_CONSTRUCTIBLE(F)
+ {
+ static F f;
+ return f;
+ }
+
+ BOOST_HOF_RETURNS_CLASS(static_);
+
+ template<class... Ts>
+ BOOST_HOF_SFINAE_RESULT(F, id_<Ts>...)
+ operator()(Ts && ... xs) const
+ BOOST_HOF_SFINAE_RETURNS(BOOST_HOF_CONST_THIS->base_function()(BOOST_HOF_FORWARD(Ts)(xs)...));
+};
+
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/tap.hpp b/boost/hof/tap.hpp
new file mode 100644
index 0000000000..ab265c29ae
--- /dev/null
+++ b/boost/hof/tap.hpp
@@ -0,0 +1,83 @@
+/*=============================================================================
+ Copyright (c) 2014 Paul Fultz II
+ tap.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_FUNCTION_TAP_H
+#define BOOST_HOF_GUARD_FUNCTION_TAP_H
+
+/// tap
+/// ===
+///
+/// Description
+/// -----------
+///
+/// The `tap` function invokes a function on the first argument passed in and
+/// then returns the first argument. This is useful in a chain of pipable
+/// function to perform operations on intermediate results. As a result, this
+/// function is [`pipable`](/include/boost/hof/pipable).
+///
+/// Synopsis
+/// --------
+///
+/// template<class T, class F>
+/// pipable constexpr T tap(T&& x, const F& f);
+///
+/// Requirements
+/// ------------
+///
+/// F must be:
+///
+/// * [UnaryInvocable](UnaryInvocable)
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+/// #include <iostream>
+/// using namespace boost::hof;
+///
+/// struct sum_f
+/// {
+/// template<class T, class U>
+/// T operator()(T x, U y) const
+/// {
+/// return x+y;
+/// }
+/// };
+///
+/// const pipable_adaptor<sum_f> sum = {};
+/// int main() {
+/// // Prints 3
+/// int r = 1 | sum(2) | tap([](int i) { std::cout << i; }) | sum(2);
+/// assert(r == 5);
+/// }
+///
+
+#include <boost/hof/pipable.hpp>
+#include <boost/hof/apply.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+
+namespace boost { namespace hof { namespace detail {
+
+struct tap_f
+{
+ template<class T, class F>
+ constexpr T operator()(T&& x, const F& f) const
+ BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT((boost::hof::apply(f, x), BOOST_HOF_FORWARD(T)(x)))
+ {
+ return boost::hof::apply(f, x), BOOST_HOF_FORWARD(T)(x);
+ }
+};
+
+}
+
+BOOST_HOF_DECLARE_STATIC_VAR(tap, pipable_adaptor<detail::tap_f>);
+
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/unpack.hpp b/boost/hof/unpack.hpp
new file mode 100644
index 0000000000..cfbec80e82
--- /dev/null
+++ b/boost/hof/unpack.hpp
@@ -0,0 +1,181 @@
+/*=============================================================================
+ Copyright (c) 2015 Paul Fultz II
+ unpack.h
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_UNPACK_H
+#define BOOST_HOF_GUARD_UNPACK_H
+
+/// unpack
+/// ======
+///
+/// Description
+/// -----------
+///
+/// The `unpack` function adaptor takes a sequence and uses the elements of
+/// the sequence for the arguments to the function. Multiple sequences can be
+/// passed to the function. All elements from each sequence will be passed
+/// into the function.
+///
+///
+/// Synopsis
+/// --------
+///
+/// template<class F>
+/// unpack_adaptor<F> unpack(F f);
+///
+/// Requirements
+/// ------------
+///
+/// F must be:
+///
+/// * [ConstInvocable](ConstInvocable)
+/// * MoveConstructible
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+/// using namespace boost::hof;
+///
+/// struct sum
+/// {
+/// template<class T, class U>
+/// T operator()(T x, U y) const
+/// {
+/// return x+y;
+/// }
+/// };
+///
+/// int main() {
+/// int r = unpack(sum())(std::make_tuple(3,2));
+/// assert(r == 5);
+/// }
+///
+/// References
+/// ----------
+///
+/// * [std::apply](http://en.cppreference.com/w/cpp/utility/apply) - C++17 function to unpack a tuple
+/// * [`unpack_sequence`](unpack_sequence)
+///
+
+#include <boost/hof/unpack_sequence.hpp>
+#include <boost/hof/is_unpackable.hpp>
+#include <boost/hof/detail/seq.hpp>
+#include <boost/hof/capture.hpp>
+#include <boost/hof/always.hpp>
+#include <boost/hof/reveal.hpp>
+#include <boost/hof/detail/and.hpp>
+#include <boost/hof/detail/delegate.hpp>
+#include <boost/hof/detail/holder.hpp>
+#include <boost/hof/detail/move.hpp>
+#include <boost/hof/detail/make.hpp>
+#include <boost/hof/detail/static_const_var.hpp>
+
+namespace boost { namespace hof {
+
+namespace detail {
+
+template<class F, class Sequence>
+constexpr auto unpack_simple(F&& f, Sequence&& s) BOOST_HOF_RETURNS
+(
+ detail::unpack_impl(BOOST_HOF_FORWARD(F)(f), BOOST_HOF_FORWARD(Sequence)(s))
+)
+
+template<class F, class... Sequences>
+constexpr auto unpack_join(F&& f, Sequences&&... s) BOOST_HOF_RETURNS
+(
+ boost::hof::pack_join(unpack_simple(boost::hof::pack_forward, BOOST_HOF_FORWARD(Sequences)(s))...)(BOOST_HOF_FORWARD(F)(f))
+);
+
+}
+
+template<class F>
+struct unpack_adaptor : detail::callable_base<F>
+{
+ typedef unpack_adaptor fit_rewritable1_tag;
+ BOOST_HOF_INHERIT_CONSTRUCTOR(unpack_adaptor, detail::callable_base<F>);
+
+ template<class... Ts>
+ constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const noexcept
+ {
+ return boost::hof::always_ref(*this)(xs...);
+ }
+
+ struct unpack_failure
+ {
+ template<class Failure>
+ struct apply
+ {
+ struct deducer
+ {
+ template<class... Ts>
+ typename Failure::template of<Ts...> operator()(Ts&&...) const;
+ };
+
+ template<class T, class=typename std::enable_if<(
+ is_unpackable<T>::value
+ )>::type>
+ static auto deduce(T&& x)
+ BOOST_HOF_RETURNS
+ (
+ boost::hof::detail::unpack_simple(deducer(), BOOST_HOF_FORWARD(T)(x))
+ );
+
+ template<class T, class... Ts, class=typename std::enable_if<(
+ is_unpackable<T>::value && BOOST_HOF_AND_UNPACK(is_unpackable<Ts>::value)
+ )>::type>
+ static auto deduce(T&& x, Ts&&... xs) BOOST_HOF_RETURNS
+ (
+ boost::hof::detail::unpack_join(deducer(), BOOST_HOF_FORWARD(T)(x), BOOST_HOF_FORWARD(Ts)(xs)...)
+ );
+#ifdef _MSC_VER
+ template<class... Ts>
+ struct nop_failure;
+ template<class... Ts, class=typename std::enable_if<(
+ !BOOST_HOF_AND_UNPACK(is_unpackable<Ts>::value)
+ )>::type>
+ static as_failure<nop_failure> deduce(Ts&&... xs);
+#endif
+ template<class... Ts>
+ struct of
+#if (defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7) || defined (_MSC_VER)
+ : std::enable_if<true, decltype(apply::deduce(std::declval<Ts>()...))>::type
+#else
+ : decltype(apply::deduce(std::declval<Ts>()...))
+#endif
+ {};
+ };
+ };
+
+ struct failure
+ : failure_map<unpack_failure, detail::callable_base<F>>
+ {};
+
+ BOOST_HOF_RETURNS_CLASS(unpack_adaptor);
+ template<class T, class=typename std::enable_if<(
+ is_unpackable<T>::value
+ )>::type>
+ constexpr auto operator()(T&& x) const
+ BOOST_HOF_RETURNS
+ (
+ boost::hof::detail::unpack_simple(BOOST_HOF_MANGLE_CAST(const detail::callable_base<F>&)(BOOST_HOF_CONST_THIS->base_function(x)), BOOST_HOF_FORWARD(T)(x))
+ );
+
+ template<class T, class... Ts, class=typename std::enable_if<(
+ is_unpackable<T>::value && BOOST_HOF_AND_UNPACK(is_unpackable<Ts>::value)
+ )>::type>
+ constexpr auto operator()(T&& x, Ts&&... xs) const BOOST_HOF_RETURNS
+ (
+ boost::hof::detail::unpack_join(BOOST_HOF_MANGLE_CAST(const detail::callable_base<F>&)(BOOST_HOF_CONST_THIS->base_function(x)), BOOST_HOF_FORWARD(T)(x), BOOST_HOF_FORWARD(Ts)(xs)...)
+ );
+};
+
+BOOST_HOF_DECLARE_STATIC_VAR(unpack, detail::make<unpack_adaptor>);
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/unpack_sequence.hpp b/boost/hof/unpack_sequence.hpp
new file mode 100644
index 0000000000..1e6a439f21
--- /dev/null
+++ b/boost/hof/unpack_sequence.hpp
@@ -0,0 +1,71 @@
+/*=============================================================================
+ Copyright (c) 2016 Paul Fultz II
+ unpack_sequence.hpp
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_UNPACK_SEQUENCE_HPP
+#define BOOST_HOF_GUARD_UNPACK_SEQUENCE_HPP
+
+/// unpack_sequence
+/// ===============
+///
+/// How to unpack a sequence can be defined by specializing `unpack_sequence`.
+/// By default, `std::tuple` is already specialized. To implement this, one
+/// needs to provide a static `apply` function which will unpack the sequence
+/// to the parameters of the function.
+///
+/// Synopsis
+/// --------
+///
+/// template<class Sequence, class=void>
+/// struct unpack_sequence;
+///
+/// Example
+/// -------
+///
+/// #include <boost/hof.hpp>
+/// #include <cassert>
+///
+/// struct my_sequence
+/// {
+/// int x;
+/// int y;
+/// };
+///
+/// namespace boost { namespace hof {
+/// template<>
+/// struct unpack_sequence<my_sequence>
+/// {
+/// template<class F, class Sequence>
+/// constexpr static auto apply(F&& f, Sequence&& s) BOOST_HOF_RETURNS
+/// (
+/// f(s.x, s.y)
+/// );
+/// };
+/// }} // namespace boost::hof
+///
+/// int main() {
+/// }
+///
+/// See Also
+/// --------
+///
+/// * [unpack](unpack)
+/// * [is_unpackable](is_unpackable)
+///
+
+#include <boost/hof/config.hpp>
+
+namespace boost { namespace hof {
+
+template<class Sequence, class=void>
+struct unpack_sequence
+{
+ typedef void not_unpackable;
+};
+
+}} // namespace boost::hof
+
+#endif
diff --git a/boost/hof/version.hpp b/boost/hof/version.hpp
new file mode 100644
index 0000000000..824104c62b
--- /dev/null
+++ b/boost/hof/version.hpp
@@ -0,0 +1,16 @@
+/*=============================================================================
+ Copyright (c) 2016 Paul Fultz II
+ version.hpp
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_VERSION_HPP
+#define BOOST_HOF_GUARD_VERSION_HPP
+
+#define BOOST_HOF_VERSION_MAJOR 0
+#define BOOST_HOF_VERSION_MINOR 6
+#define BOOST_HOF_VERSION_PATCH 0
+#define BOOST_HOF_VERSION (((BOOST_HOF_VERSION_MAJOR) << 24) + ((BOOST_HOF_VERSION_MINOR) << 16) + (BOOST_HOF_VERSION_PATCH))
+
+#endif