summaryrefslogtreecommitdiff
path: root/boost/hof/detail
diff options
context:
space:
mode:
Diffstat (limited to 'boost/hof/detail')
-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
23 files changed, 1371 insertions, 0 deletions
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