summaryrefslogtreecommitdiff
path: root/boost/functional
diff options
context:
space:
mode:
Diffstat (limited to 'boost/functional')
-rw-r--r--boost/functional/detail/container_fwd.hpp14
-rw-r--r--boost/functional/hash/detail/container_fwd_0x.hpp29
-rw-r--r--boost/functional/hash/detail/hash_float.hpp16
-rw-r--r--boost/functional/hash/extensions.hpp101
-rw-r--r--boost/functional/hash/hash.hpp172
-rw-r--r--boost/functional/overloaded_function.hpp311
-rw-r--r--boost/functional/overloaded_function/config.hpp50
-rw-r--r--boost/functional/overloaded_function/detail/base.hpp86
-rw-r--r--boost/functional/overloaded_function/detail/function_type.hpp85
9 files changed, 744 insertions, 120 deletions
diff --git a/boost/functional/detail/container_fwd.hpp b/boost/functional/detail/container_fwd.hpp
index 9a69d155b2..e2bf86526c 100644
--- a/boost/functional/detail/container_fwd.hpp
+++ b/boost/functional/detail/container_fwd.hpp
@@ -1,11 +1,11 @@
-// Copyright 2005-2008 Daniel James.
+// Copyright 2005-2012 Daniel James.
// 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)
// Forwarding header for container_fwd.hpp's new location.
-// This header is deprecated, I'll be adding a warning in a future release,
-// then converting it to an error and finally removing this header completely.
+// This header is deprecated, I'll change the warning to an error in a future
+// release, and then later remove the header completely.
#if !defined(BOOST_FUNCTIONAL_DETAIL_CONTAINER_FWD_HPP)
#define BOOST_FUNCTIONAL_DETAIL_CONTAINER_FWD_HPP
@@ -14,6 +14,14 @@
# pragma once
#endif
+#if defined(__EDG__)
+#elif defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
+#pragma message("Warning: boost/functional/detail/container_fwd.hpp is deprecated, use boost/detail/container_fwd.hpp instead.")
+#elif defined(__GNUC__) || defined(__HP_aCC) || \
+ defined(__SUNPRO_CC) || defined(__IBMCPP__)
+#warning "boost/functional/detail/container_fwd.hpp is deprecated, use boost/detail/container_fwd.hpp instead."
+#endif
+
#include <boost/detail/container_fwd.hpp>
#endif
diff --git a/boost/functional/hash/detail/container_fwd_0x.hpp b/boost/functional/hash/detail/container_fwd_0x.hpp
new file mode 100644
index 0000000000..bed7730fc0
--- /dev/null
+++ b/boost/functional/hash/detail/container_fwd_0x.hpp
@@ -0,0 +1,29 @@
+
+// Copyright 2012 Daniel James.
+// 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)
+
+#if !defined(BOOST_DETAIL_CONTAINER_FWD_0X_HPP)
+#define BOOST_DETAIL_CONTAINER_FWD_0X_HPP
+
+#include <boost/detail/container_fwd.hpp>
+
+// std::array
+
+#if !defined(BOOST_NO_CXX11_HDR_ARRAY)
+# include <array>
+#endif
+
+// std::tuple
+
+#if !defined(BOOST_NO_CXX11_HDR_TUPLE)
+# include <tuple>
+#endif
+
+// std::shared_ptr/std::unique_ptr
+
+#if !defined(BOOST_NO_CXX11_HDR_MEMORY)
+# include <memory>
+#endif
+
+#endif
diff --git a/boost/functional/hash/detail/hash_float.hpp b/boost/functional/hash/detail/hash_float.hpp
index ea1bc25f48..194be1cae5 100644
--- a/boost/functional/hash/detail/hash_float.hpp
+++ b/boost/functional/hash/detail/hash_float.hpp
@@ -87,9 +87,23 @@ namespace boost
namespace hash_detail
{
template <class T>
+ inline bool is_zero(T v)
+ {
+#if !defined(__GNUC__)
+ return v == 0;
+#else
+ // GCC's '-Wfloat-equal' will complain about comparing
+ // v to 0, but because it disables warnings for system
+ // headers it won't complain if you use std::equal_to to
+ // compare with 0. Resulting in this silliness:
+ return std::equal_to<T>()(v, 0);
+#endif
+ }
+
+ template <class T>
inline std::size_t float_hash_value(T v)
{
- return v == 0 ? 0 : float_hash_impl(v);
+ return boost::hash_detail::is_zero(v) ? 0 : float_hash_impl(v);
}
}
}
diff --git a/boost/functional/hash/extensions.hpp b/boost/functional/hash/extensions.hpp
index 3c587a3bf5..4358736b26 100644
--- a/boost/functional/hash/extensions.hpp
+++ b/boost/functional/hash/extensions.hpp
@@ -14,7 +14,11 @@
#define BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP
#include <boost/functional/hash/hash.hpp>
-#include <boost/detail/container_fwd.hpp>
+#include <boost/functional/hash/detail/container_fwd_0x.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
@@ -54,51 +58,51 @@ namespace boost
std::size_t hash_value(std::pair<A, B> const& v)
{
std::size_t seed = 0;
- hash_combine(seed, v.first);
- hash_combine(seed, v.second);
+ boost::hash_combine(seed, v.first);
+ boost::hash_combine(seed, v.second);
return seed;
}
template <class T, class A>
std::size_t hash_value(std::vector<T, A> const& v)
{
- return hash_range(v.begin(), v.end());
+ return boost::hash_range(v.begin(), v.end());
}
template <class T, class A>
std::size_t hash_value(std::list<T, A> const& v)
{
- return hash_range(v.begin(), v.end());
+ return boost::hash_range(v.begin(), v.end());
}
template <class T, class A>
std::size_t hash_value(std::deque<T, A> const& v)
{
- return hash_range(v.begin(), v.end());
+ return boost::hash_range(v.begin(), v.end());
}
template <class K, class C, class A>
std::size_t hash_value(std::set<K, C, A> const& v)
{
- return hash_range(v.begin(), v.end());
+ return boost::hash_range(v.begin(), v.end());
}
template <class K, class C, class A>
std::size_t hash_value(std::multiset<K, C, A> const& v)
{
- return hash_range(v.begin(), v.end());
+ return boost::hash_range(v.begin(), v.end());
}
template <class K, class T, class C, class A>
std::size_t hash_value(std::map<K, T, C, A> const& v)
{
- return hash_range(v.begin(), v.end());
+ return boost::hash_range(v.begin(), v.end());
}
template <class K, class T, class C, class A>
std::size_t hash_value(std::multimap<K, T, C, A> const& v)
{
- return hash_range(v.begin(), v.end());
+ return boost::hash_range(v.begin(), v.end());
}
template <class T>
@@ -110,6 +114,83 @@ namespace boost
return seed;
}
+#if !defined(BOOST_NO_CXX11_HDR_ARRAY)
+ template <class T, std::size_t N>
+ std::size_t hash_value(std::array<T, N> const& v)
+ {
+ return boost::hash_range(v.begin(), v.end());
+ }
+#endif
+
+#if !defined(BOOST_NO_CXX11_HDR_TUPLE)
+ namespace hash_detail {
+ template <std::size_t I, typename T>
+ inline typename boost::enable_if_c<(I == std::tuple_size<T>::value),
+ void>::type
+ hash_combine_tuple(std::size_t&, T const&)
+ {
+ }
+
+ template <std::size_t I, typename T>
+ inline typename boost::enable_if_c<(I < std::tuple_size<T>::value),
+ void>::type
+ hash_combine_tuple(std::size_t& seed, T const& v)
+ {
+ boost::hash_combine(seed, std::get<I>(v));
+ boost::hash_detail::hash_combine_tuple<I + 1>(seed, v);
+ }
+
+ template <typename T>
+ inline std::size_t hash_tuple(T const& v)
+ {
+ std::size_t seed = 0;
+ boost::hash_detail::hash_combine_tuple<0>(seed, v);
+ return seed;
+ }
+ }
+
+#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+ template <typename... T>
+ inline std::size_t hash_value(std::tuple<T...> const& v)
+ {
+ return boost::hash_detail::hash_tuple(v);
+ }
+#else
+
+ inline std::size_t hash_value(std::tuple<> const& v)
+ {
+ return boost::hash_detail::hash_tuple(v);
+ }
+
+# define BOOST_HASH_TUPLE_F(z, n, _) \
+ template< \
+ BOOST_PP_ENUM_PARAMS_Z(z, n, typename A) \
+ > \
+ inline std::size_t hash_value(std::tuple< \
+ BOOST_PP_ENUM_PARAMS_Z(z, n, A) \
+ > const& v) \
+ { \
+ return boost::hash_detail::hash_tuple(v); \
+ }
+
+ BOOST_PP_REPEAT_FROM_TO(1, 11, BOOST_HASH_TUPLE_F, _)
+# undef BOOST_HASH_TUPLE_F
+#endif
+
+#endif
+
+#if !defined(BOOST_NO_CXX11_SMART_PTR)
+ template <typename T>
+ inline std::size_t hash_value(std::shared_ptr<T> const& x) {
+ return boost::hash_value(x.get());
+ }
+
+ template <typename T, typename Deleter>
+ inline std::size_t hash_value(std::unique_ptr<T, Deleter> const& x) {
+ return boost::hash_value(x.get());
+ }
+#endif
+
//
// call_hash_impl
//
diff --git a/boost/functional/hash/hash.hpp b/boost/functional/hash/hash.hpp
index 51ec8608c8..c179fab69a 100644
--- a/boost/functional/hash/hash.hpp
+++ b/boost/functional/hash/hash.hpp
@@ -16,15 +16,11 @@
#include <string>
#include <boost/limits.hpp>
-#if defined(BOOST_HASH_NO_IMPLICIT_CASTS)
-#include <boost/static_assert.hpp>
-#endif
-
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
#include <boost/type_traits/is_pointer.hpp>
#endif
-#if !defined(BOOST_NO_0X_HDR_TYPEINDEX)
+#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
#include <typeindex>
#endif
@@ -37,38 +33,63 @@
namespace boost
{
-#if defined(BOOST_HASH_NO_IMPLICIT_CASTS)
-
- // If you get a static assertion here, it's because hash_value
- // isn't declared for your type.
- template <typename T>
- std::size_t hash_value(T const&) {
- BOOST_STATIC_ASSERT((T*) 0 && false);
- return 0;
- }
-
-#endif
-
- std::size_t hash_value(bool);
- std::size_t hash_value(char);
- std::size_t hash_value(unsigned char);
- std::size_t hash_value(signed char);
- std::size_t hash_value(short);
- std::size_t hash_value(unsigned short);
- std::size_t hash_value(int);
- std::size_t hash_value(unsigned int);
- std::size_t hash_value(long);
- std::size_t hash_value(unsigned long);
+ namespace hash_detail
+ {
+ struct enable_hash_value { typedef std::size_t type; };
+
+ template <typename T> struct basic_numbers {};
+ template <typename T> struct long_numbers {};
+ template <typename T> struct ulong_numbers {};
+ template <typename T> struct float_numbers {};
+
+ template <> struct basic_numbers<bool> :
+ boost::hash_detail::enable_hash_value {};
+ template <> struct basic_numbers<char> :
+ boost::hash_detail::enable_hash_value {};
+ template <> struct basic_numbers<unsigned char> :
+ boost::hash_detail::enable_hash_value {};
+ template <> struct basic_numbers<signed char> :
+ boost::hash_detail::enable_hash_value {};
+ template <> struct basic_numbers<short> :
+ boost::hash_detail::enable_hash_value {};
+ template <> struct basic_numbers<unsigned short> :
+ boost::hash_detail::enable_hash_value {};
+ template <> struct basic_numbers<int> :
+ boost::hash_detail::enable_hash_value {};
+ template <> struct basic_numbers<unsigned int> :
+ boost::hash_detail::enable_hash_value {};
+ template <> struct basic_numbers<long> :
+ boost::hash_detail::enable_hash_value {};
+ template <> struct basic_numbers<unsigned long> :
+ boost::hash_detail::enable_hash_value {};
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
- std::size_t hash_value(wchar_t);
+ template <> struct basic_numbers<wchar_t> :
+ boost::hash_detail::enable_hash_value {};
#endif
-
+
#if !defined(BOOST_NO_LONG_LONG)
- std::size_t hash_value(boost::long_long_type);
- std::size_t hash_value(boost::ulong_long_type);
+ template <> struct long_numbers<boost::long_long_type> :
+ boost::hash_detail::enable_hash_value {};
+ template <> struct ulong_numbers<boost::ulong_long_type> :
+ boost::hash_detail::enable_hash_value {};
#endif
+ template <> struct float_numbers<float> :
+ boost::hash_detail::enable_hash_value {};
+ template <> struct float_numbers<double> :
+ boost::hash_detail::enable_hash_value {};
+ template <> struct float_numbers<long double> :
+ boost::hash_detail::enable_hash_value {};
+ }
+
+ template <typename T>
+ typename boost::hash_detail::basic_numbers<T>::type hash_value(T);
+ template <typename T>
+ typename boost::hash_detail::long_numbers<T>::type hash_value(T);
+ template <typename T>
+ typename boost::hash_detail::ulong_numbers<T>::type hash_value(T);
+
#if !BOOST_WORKAROUND(__DMC__, <= 0x848)
template <class T> std::size_t hash_value(T* const&);
#else
@@ -83,15 +104,14 @@ namespace boost
std::size_t hash_value(T (&x)[N]);
#endif
- std::size_t hash_value(float v);
- std::size_t hash_value(double v);
- std::size_t hash_value(long double v);
-
template <class Ch, class A>
std::size_t hash_value(
std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const&);
-#if !defined(BOOST_NO_0X_HDR_TYPEINDEX)
+ template <typename T>
+ typename boost::hash_detail::float_numbers<T>::type hash_value(T);
+
+#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
std::size_t hash_value(std::type_index);
#endif
@@ -141,74 +161,23 @@ namespace boost
}
}
- inline std::size_t hash_value(bool v)
- {
- return static_cast<std::size_t>(v);
- }
-
- inline std::size_t hash_value(char v)
- {
- return static_cast<std::size_t>(v);
- }
-
- inline std::size_t hash_value(unsigned char v)
- {
- return static_cast<std::size_t>(v);
- }
-
- inline std::size_t hash_value(signed char v)
- {
- return static_cast<std::size_t>(v);
- }
-
- inline std::size_t hash_value(short v)
- {
- return static_cast<std::size_t>(v);
- }
-
- inline std::size_t hash_value(unsigned short v)
- {
- return static_cast<std::size_t>(v);
- }
-
- inline std::size_t hash_value(int v)
- {
- return static_cast<std::size_t>(v);
- }
-
- inline std::size_t hash_value(unsigned int v)
- {
- return static_cast<std::size_t>(v);
- }
-
- inline std::size_t hash_value(long v)
- {
- return static_cast<std::size_t>(v);
- }
-
- inline std::size_t hash_value(unsigned long v)
- {
- return static_cast<std::size_t>(v);
- }
-
-#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
- inline std::size_t hash_value(wchar_t v)
+ template <typename T>
+ typename boost::hash_detail::basic_numbers<T>::type hash_value(T v)
{
return static_cast<std::size_t>(v);
}
-#endif
-#if !defined(BOOST_NO_LONG_LONG)
- inline std::size_t hash_value(boost::long_long_type v)
+ template <typename T>
+ typename boost::hash_detail::long_numbers<T>::type hash_value(T v)
{
return hash_detail::hash_value_signed(v);
}
- inline std::size_t hash_value(boost::ulong_long_type v)
+ template <typename T>
+ typename boost::hash_detail::ulong_numbers<T>::type hash_value(T v)
{
return hash_detail::hash_value_unsigned(v);
}
-#endif
// Implementation by Alberto Barbati and Dave Harris.
#if !BOOST_WORKAROUND(__DMC__, <= 0x848)
@@ -324,22 +293,13 @@ namespace boost
return hash_range(v.begin(), v.end());
}
- inline std::size_t hash_value(float v)
- {
- return boost::hash_detail::float_hash_value(v);
- }
-
- inline std::size_t hash_value(double v)
- {
- return boost::hash_detail::float_hash_value(v);
- }
-
- inline std::size_t hash_value(long double v)
+ template <typename T>
+ typename boost::hash_detail::float_numbers<T>::type hash_value(T v)
{
return boost::hash_detail::float_hash_value(v);
}
-#if !defined(BOOST_NO_0X_HDR_TYPEINDEX)
+#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
inline std::size_t hash_value(std::type_index v)
{
return v.hash_code();
@@ -450,7 +410,7 @@ namespace boost
BOOST_HASH_SPECIALIZE(boost::ulong_long_type)
#endif
-#if !defined(BOOST_NO_0X_HDR_TYPEINDEX)
+#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
BOOST_HASH_SPECIALIZE(std::type_index)
#endif
diff --git a/boost/functional/overloaded_function.hpp b/boost/functional/overloaded_function.hpp
new file mode 100644
index 0000000000..83fe4b3849
--- /dev/null
+++ b/boost/functional/overloaded_function.hpp
@@ -0,0 +1,311 @@
+
+// Copyright (C) 2009-2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/functional/overloaded_function
+
+#ifndef DOXYGEN // Doxygen documentation only.
+
+#if !BOOST_PP_IS_ITERATING
+# ifndef BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_HPP_
+# define BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_HPP_
+
+# include <boost/functional/overloaded_function/detail/base.hpp>
+# include <boost/functional/overloaded_function/detail/function_type.hpp>
+# include <boost/functional/overloaded_function/config.hpp>
+# include <boost/typeof/typeof.hpp>
+# include <boost/preprocessor/iteration/iterate.hpp>
+# include <boost/preprocessor/repetition/enum.hpp>
+# include <boost/preprocessor/repetition/repeat.hpp>
+# include <boost/preprocessor/control/expr_iif.hpp>
+# include <boost/preprocessor/control/expr_if.hpp>
+# include <boost/preprocessor/comparison/greater.hpp>
+# include <boost/preprocessor/comparison/less.hpp>
+# include <boost/preprocessor/cat.hpp>
+# include <boost/preprocessor/arithmetic/add.hpp>
+# include <boost/preprocessor/arithmetic/sub.hpp>
+# include <boost/preprocessor/tuple/eat.hpp>
+# include <boost/preprocessor/logical/and.hpp>
+# include <boost/preprocessor/logical/not.hpp>
+# include <boost/preprocessor/facilities/expand.hpp>
+
+#define BOOST_FUNCTIONAL_f_type(z, n, unused) \
+ BOOST_PP_CAT(F, n)
+
+#define BOOST_FUNCTIONAL_f_arg(z, n, unused) \
+ BOOST_PP_CAT(f, n)
+
+#define BOOST_FUNCTIONAL_f_tparam(z, n, unused) \
+ typename BOOST_FUNCTIONAL_f_type(z, n, ~) \
+
+#define BOOST_FUNCTIONAL_f_tparam_dflt(z, n, is_tspec) \
+ BOOST_FUNCTIONAL_f_tparam(z, n, ~) \
+ /* overload requires at least 2 functors so F0 and F1 not optional */ \
+ BOOST_PP_EXPR_IIF(BOOST_PP_AND(BOOST_PP_NOT(is_tspec), \
+ BOOST_PP_GREATER(n, 1)), \
+ = void \
+ )
+
+#define BOOST_FUNCTIONAL_f_arg_decl(z, n, unused) \
+ BOOST_FUNCTIONAL_f_type(z, n, ~) /* no qualifier to deduce tparam */ \
+ BOOST_FUNCTIONAL_f_arg(z, n, ~)
+
+#define BOOST_FUNCTIONAL_g_type(z, n, unused) \
+ BOOST_PP_CAT(G, n)
+
+#define BOOST_FUNCTIONAL_g_arg(z, n, unused) \
+ BOOST_PP_CAT(g, n)
+
+#define BOOST_FUNCTIONAL_g_tparam(z, n, unused) \
+ typename BOOST_FUNCTIONAL_g_type(z, n, ~)
+
+#define BOOST_FUNCTIONAL_g_arg_decl(z, n, unused) \
+ BOOST_FUNCTIONAL_g_type(z, n, ~) /* no qualifier to deduce tparam */ \
+ BOOST_FUNCTIONAL_g_arg(z, n, ~)
+
+#define BOOST_FUNCTIONAL_base(z, n, unused) \
+ ::boost::overloaded_function_detail::base< \
+ BOOST_FUNCTIONAL_f_type(z, n, ~) \
+ >
+
+#define BOOST_FUNCTIONAL_inherit(z, n, unused) \
+ public BOOST_FUNCTIONAL_base(z, n, ~)
+
+#define BOOST_FUNCTIONAL_base_init(z, n, unused) \
+ BOOST_FUNCTIONAL_base(z, n, ~)(BOOST_FUNCTIONAL_g_arg(z, n, ~))
+
+#define BOOST_FUNCTIONAL_using_operator_call(z, n, unused) \
+ using BOOST_FUNCTIONAL_base(z, n, ~)::operator();
+
+#define BOOST_FUNCTIONAL_function_type(z, n, unused) \
+ typename ::boost::overloaded_function_detail::function_type< \
+ BOOST_FUNCTIONAL_f_type(z, n, ~) \
+ >::type
+
+# define BOOST_PP_ITERATION_PARAMS_1 \
+ /* at least 2 func to overload so start from 2 to MAX */ \
+ /* (cannot iterate [0, MAX-2) because error on Sun) */ \
+ (3, (2, BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX, \
+ "boost/functional/overloaded_function.hpp"))
+# include BOOST_PP_ITERATE() // Iterate over function arity.
+
+#undef BOOST_FUNCTIONAL_f_type
+#undef BOOST_FUNCTIONAL_f_arg
+#undef BOOST_FUNCTIONAL_f_tparam
+#undef BOOST_FUNCTIONAL_f_arg_decl
+#undef BOOST_FUNCTIONAL_f_tparam_dflt
+#undef BOOST_FUNCTIONAL_g_type
+#undef BOOST_FUNCTIONAL_g_arg
+#undef BOOST_FUNCTIONAL_g_tparam
+#undef BOOST_FUNCTIONAL_g_arg_decl
+#undef BOOST_FUNCTIONAL_base
+#undef BOOST_FUNCTIONAL_inherit
+#undef BOOST_FUNCTIONAL_base_init
+#undef BOOST_FUNCTIONAL_using_operator_call
+#undef BOOST_FUNCTIONAL_function_type
+
+# endif // #include guard
+
+#elif BOOST_PP_ITERATION_DEPTH() == 1
+# define BOOST_FUNCTIONAL_overloads \
+ /* iterate as OVERLOADS, OVERLOADS-1, OVERLOADS-2, ... */ \
+ /* (add 2 because iteration started from 2 to MAX) */ \
+ BOOST_PP_ADD(2, BOOST_PP_SUB( \
+ BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX, \
+ BOOST_PP_FRAME_ITERATION(1)))
+# define BOOST_FUNCTIONAL_is_tspec \
+ /* if template specialization */ \
+ BOOST_PP_LESS(BOOST_FUNCTIONAL_overloads, \
+ BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX)
+
+// For type-of emulation: This must be included at this pp iteration level.
+# include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+
+namespace boost {
+
+template<
+ BOOST_PP_ENUM(BOOST_FUNCTIONAL_overloads, BOOST_FUNCTIONAL_f_tparam_dflt,
+ BOOST_FUNCTIONAL_is_tspec)
+>
+class overloaded_function
+ // Template specialization.
+ BOOST_PP_EXPR_IIF(BOOST_PP_EXPAND(BOOST_FUNCTIONAL_is_tspec), <)
+ BOOST_PP_IIF(BOOST_FUNCTIONAL_is_tspec,
+ BOOST_PP_ENUM
+ ,
+ BOOST_PP_TUPLE_EAT(3)
+ )(BOOST_FUNCTIONAL_overloads, BOOST_FUNCTIONAL_f_type, ~)
+ BOOST_PP_EXPR_IIF(BOOST_PP_EXPAND(BOOST_FUNCTIONAL_is_tspec), >)
+ // Bases (overloads >= 2 so always at least 2 bases).
+ : BOOST_PP_ENUM(BOOST_FUNCTIONAL_overloads,
+ BOOST_FUNCTIONAL_inherit, ~)
+{
+public:
+ template<
+ BOOST_PP_ENUM(BOOST_FUNCTIONAL_overloads, BOOST_FUNCTIONAL_g_tparam, ~)
+ > /* implicit */ inline overloaded_function(
+ BOOST_PP_ENUM(BOOST_FUNCTIONAL_overloads,
+ BOOST_FUNCTIONAL_g_arg_decl, ~))
+ // Overloads >= 2 so always at least 2 bases to initialize.
+ : BOOST_PP_ENUM(BOOST_FUNCTIONAL_overloads,
+ BOOST_FUNCTIONAL_base_init, ~)
+ {}
+
+ BOOST_PP_REPEAT(BOOST_FUNCTIONAL_overloads,
+ BOOST_FUNCTIONAL_using_operator_call, ~)
+};
+
+template<
+ BOOST_PP_ENUM(BOOST_FUNCTIONAL_overloads, BOOST_FUNCTIONAL_f_tparam, ~)
+>
+overloaded_function<
+ BOOST_PP_ENUM(BOOST_FUNCTIONAL_overloads, BOOST_FUNCTIONAL_function_type, ~)
+> make_overloaded_function(
+ BOOST_PP_ENUM(BOOST_FUNCTIONAL_overloads, BOOST_FUNCTIONAL_f_arg_decl, ~)
+) {
+ return overloaded_function<
+ BOOST_PP_ENUM(BOOST_FUNCTIONAL_overloads,
+ BOOST_FUNCTIONAL_function_type, ~)
+ >(BOOST_PP_ENUM(BOOST_FUNCTIONAL_overloads, BOOST_FUNCTIONAL_f_arg, ~));
+}
+
+} // namespace
+
+// For type-of emulation: Register overloaded function type (for _AUTO, etc).
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::overloaded_function,
+ BOOST_FUNCTIONAL_overloads)
+
+# undef BOOST_FUNCTIONAL_overloads
+# undef BOOST_FUNCTIONAL_is_tspec
+#endif // iteration
+
+// DOCUMENTATION //
+
+#else // DOXYGEN
+
+/** @file
+@brief Overload distinct function pointers, function references, and
+monomorphic function objects into a single function object.
+*/
+
+namespace boost {
+
+/**
+@brief Function object to overload functions with distinct signatures.
+
+This function object aggregates together calls to functions of all the
+specified function types <c>F1</c>, <c>F2</c>, etc which must have distinct
+function signatures from one another.
+
+@Params
+@Param{F<em>i</em>,
+Each function type must be specified using the following syntax (which is
+Boost.Function's preferred syntax):
+@code
+ result_type (argument1_type\, argumgnet2_type\, ...)
+@endcode
+}
+@EndParams
+
+In some cases, the @RefFunc{make_overloaded_function} function template can be
+useful to construct an overloaded function object without explicitly
+specifying the function types.
+
+At least two distinct function types must be specified (because there is
+nothing to overload between one or zero functions).
+The maximum number of functions to overload is given by the
+@RefMacro{BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX}
+configuration macro.
+The maximum number of function parameters for each of the specified function
+types is given by the
+@RefMacro{BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_ARITY_MAX}
+configuration macro.
+
+@See @RefSect{tutorial, Tutorial} section, @RefFunc{make_overloaded_function},
+@RefMacro{BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX},
+@RefMacro{BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_ARITY_MAX},
+Boost.Function.
+*/
+template<typename F1, typename F2, ...>
+class overloaded_function {
+public:
+ /**
+ @brief Construct the overloaded function object.
+
+ Any function pointer, function reference, and monomorphic function object
+ that can be converted to a <c>boost::function</c> function object can be
+ specified as parameter.
+
+ @Note Unfortunately, it is not possible to support polymorphic function
+ objects (as explained <a
+ href="http://lists.boost.org/Archives/boost/2012/03/191744.php">here</a>).
+ */
+ overloaded_function(const boost::function<F1>&,
+ const boost::function<F2>&, ...);
+
+ /**
+ @brief Call operator matching the signature of the function type specified
+ as 1st template parameter.
+
+ This will in turn invoke the call operator of the 1st function passed to
+ the constructor.
+ */
+ typename boost::function_traits<F1>::result_type operator()(
+ typename boost::function_traits<F1>::arg1_type,
+ typename boost::function_traits<F1>::arg2_type,
+ ...) const;
+
+ /**
+ @brief Call operator matching the signature of the function type specified
+ as 2nd template parameter.
+
+ This will in turn invoke the call operator of the 2nd function passed to
+ the constructor.
+
+ @Note Similar call operators are present for all specified function types
+ <c>F1</c>, <c>F2</c>, etc (even if not exhaustively listed by this
+ documentation).
+ */
+ typename boost::function_traits<F2>::result_type operator()(
+ typename boost::function_traits<F2>::arg1_type,
+ typename boost::function_traits<F2>::arg2_type,
+ ...) const;
+};
+
+/**
+@brief Make an overloaded function object without explicitly specifying the
+function types.
+
+This function template creates and returns an @RefClass{overloaded_function}
+object that overloads all the specified functions <c>f1</c>, <c>f2</c>, etc.
+
+The function types are internally determined from the template parameter types
+so they do not need to be explicitly specified.
+Therefore, this function template usually has a more concise syntax when
+compared with @RefClass{overloaded_function}.
+This is especially useful when the explicit type of the returned
+@RefClass{overloaded_function} object does not need to be known (e.g., when
+used with Boost.Typeof's <c>BOOST_AUTO</c>, C++11 <c>auto</c>, or when the
+overloaded function object is handled using a function template parameter, see
+the @RefSect{tutorial, Tutorial} section).
+
+The maximum number of functions to overload is given by the
+@RefMacro{BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX}
+configuration macro.
+
+@Note In this documentation, <c>__function_type__</c> is a placeholder for a
+symbol that is specific to the implementation of this library.
+
+@See @RefSect{tutorial, Tutorial} section, @RefClass{overloaded_function},
+@RefMacro{BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX}.
+*/
+template<typename F1, typename F2, ...>
+overloaded_function<
+ __function_type__<F1>, __function_type__<F2>, ...
+> make_overloaded_function(F1 f1, F2 f2, ...);
+
+} // namespace
+
+#endif // DOXYGEN
+
diff --git a/boost/functional/overloaded_function/config.hpp b/boost/functional/overloaded_function/config.hpp
new file mode 100644
index 0000000000..2f5d9e1323
--- /dev/null
+++ b/boost/functional/overloaded_function/config.hpp
@@ -0,0 +1,50 @@
+
+// Copyright (C) 2009-2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/functional/overloaded_function
+
+#ifndef BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_HPP_
+#define BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_HPP_
+
+/** @file
+@brief Change the compile-time configuration of this library.
+*/
+
+/**
+@brief Specify the maximum number of arguments of the functions being
+overloaded.
+
+If this macro is left undefined by the user, it has a default value of 5
+(increasing this number might increase compilation time).
+When specified by the user, this macro must be a non-negative integer number.
+
+@See @RefSect{getting_started, Getting Started},
+@RefClass{boost::overloaded_function}.
+*/
+#ifndef BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_ARITY_MAX
+# define BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_ARITY_MAX 5
+#endif
+
+/**
+@brief Specify the maximum number of functions that can be overloaded.
+
+If this macro is left undefined by the user, it has a default value of 5
+(increasing this number might increase compilation time).
+When defined by the user, this macro must be an integer number greater or
+equal than 2 (because at least two distinct functions need to be specified in
+order to define an overload).
+
+@See @RefSect{getting_started, Getting Started},
+@RefClass{boost::overloaded_function}.
+*/
+#ifndef BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX
+# define BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX 5
+#endif
+#if BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX < 2
+# error "maximum overload macro cannot be less than 2"
+#endif
+
+#endif // #include guard
+
diff --git a/boost/functional/overloaded_function/detail/base.hpp b/boost/functional/overloaded_function/detail/base.hpp
new file mode 100644
index 0000000000..8fd9a0a2c9
--- /dev/null
+++ b/boost/functional/overloaded_function/detail/base.hpp
@@ -0,0 +1,86 @@
+
+// Copyright (C) 2009-2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/functional/overloaded_function
+
+#if !BOOST_PP_IS_ITERATING
+# ifndef BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_DETAIL_BASE_HPP_
+# define BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_DETAIL_BASE_HPP_
+
+# include <boost/functional/overloaded_function/config.hpp>
+# include <boost/function.hpp>
+# include <boost/preprocessor/iteration/iterate.hpp>
+# include <boost/preprocessor/repetition/enum.hpp>
+# include <boost/preprocessor/cat.hpp>
+# include <boost/preprocessor/comma_if.hpp>
+
+#define BOOST_FUNCTIONAL_DETAIL_arg_type(z, n, unused) \
+ BOOST_PP_CAT(A, n)
+
+#define BOOST_FUNCTIONAL_DETAIL_arg_name(z, n, unused) \
+ BOOST_PP_CAT(a, n)
+
+#define BOOST_FUNCTIONAL_DETAIL_arg_tparam(z, n, unused) \
+ typename BOOST_FUNCTIONAL_DETAIL_arg_type(z, n, unused)
+
+#define BOOST_FUNCTIONAL_DETAIL_arg(z, n, unused) \
+ BOOST_FUNCTIONAL_DETAIL_arg_type(z, n, unused) \
+ BOOST_FUNCTIONAL_DETAIL_arg_name(z, n, unused)
+
+#define BOOST_FUNCTIONAL_DETAIL_f \
+ R (BOOST_PP_ENUM(BOOST_FUNCTIONAL_DETAIL_arity, \
+ BOOST_FUNCTIONAL_DETAIL_arg_type, ~))
+
+// Do not use namespace ::detail because overloaded_function is already a class.
+namespace boost { namespace overloaded_function_detail {
+
+template<typename F>
+class base {}; // Empty template cannot be used directly (only its spec).
+
+# define BOOST_PP_ITERATION_PARAMS_1 \
+ (3, (0, BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_ARITY_MAX, \
+ "boost/functional/overloaded_function/detail/base.hpp"))
+# include BOOST_PP_ITERATE() // Iterate over funciton arity.
+
+} } // namespace
+
+#undef BOOST_FUNCTIONAL_DETAIL_arg_type
+#undef BOOST_FUNCTIONAL_DETAIL_arg_name
+#undef BOOST_FUNCTIONAL_DETAIL_arg_tparam
+#undef BOOST_FUNCTIONAL_DETAIL_arg
+#undef BOOST_FUNCTIONAL_DETAIL_f
+
+# endif // #include guard
+
+#elif BOOST_PP_ITERATION_DEPTH() == 1
+# define BOOST_FUNCTIONAL_DETAIL_arity BOOST_PP_FRAME_ITERATION(1)
+
+template<
+ typename R
+ BOOST_PP_COMMA_IF(BOOST_FUNCTIONAL_DETAIL_arity)
+ BOOST_PP_ENUM(BOOST_FUNCTIONAL_DETAIL_arity,
+ BOOST_FUNCTIONAL_DETAIL_arg_tparam, ~)
+>
+class base< BOOST_FUNCTIONAL_DETAIL_f > {
+public:
+ /* implicit */ inline base(
+ // This requires specified type to be implicitly convertible to
+ // a boost::function<> functor.
+ boost::function< BOOST_FUNCTIONAL_DETAIL_f > const& f): f_(f)
+ {}
+
+ inline R operator()(BOOST_PP_ENUM(BOOST_FUNCTIONAL_DETAIL_arity,
+ BOOST_FUNCTIONAL_DETAIL_arg, ~)) const {
+ return f_(BOOST_PP_ENUM(BOOST_FUNCTIONAL_DETAIL_arity,
+ BOOST_FUNCTIONAL_DETAIL_arg_name, ~));
+ }
+
+private:
+ boost::function< BOOST_FUNCTIONAL_DETAIL_f > const f_;
+};
+
+# undef BOOST_FUNCTIONAL_DETAIL_arity
+#endif // iteration
+
diff --git a/boost/functional/overloaded_function/detail/function_type.hpp b/boost/functional/overloaded_function/detail/function_type.hpp
new file mode 100644
index 0000000000..0c28607b88
--- /dev/null
+++ b/boost/functional/overloaded_function/detail/function_type.hpp
@@ -0,0 +1,85 @@
+
+// Copyright (C) 2009-2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/functional/overloaded_function
+
+#ifndef BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_DETAIL_FUNCTION_TYPE_HPP_
+#define BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_DETAIL_FUNCTION_TYPE_HPP_
+
+#include <boost/function_types/is_function.hpp>
+#include <boost/function_types/is_function_pointer.hpp>
+#include <boost/function_types/is_function_reference.hpp>
+#include <boost/function_types/function_type.hpp>
+#include <boost/function_types/parameter_types.hpp>
+#include <boost/function_types/result_type.hpp>
+#include <boost/type_traits/remove_pointer.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/function.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/pop_front.hpp>
+#include <boost/mpl/push_front.hpp>
+#include <boost/typeof/typeof.hpp>
+
+// Do not use namespace ::detail because overloaded_function is already a class.
+namespace boost { namespace overloaded_function_detail {
+
+// Requires: F is a monomorphic functor (i.e., has non-template `operator()`).
+// Returns: F's function type `result_type (arg1_type, arg2_type, ...)`.
+// It does not assume F typedef result_type, arg1_type, ... but needs typeof.
+template<typename F>
+class functor_type {
+ // NOTE: clang does not accept extra parenthesis `&(...)`.
+ typedef BOOST_TYPEOF_TPL(&F::operator()) call_ptr;
+public:
+ typedef
+ typename boost::function_types::function_type<
+ typename boost::mpl::push_front<
+ typename boost::mpl::pop_front< // Remove functor type (1st).
+ typename boost::function_types::parameter_types<
+ call_ptr>::type
+ >::type
+ , typename boost::function_types::result_type<call_ptr>::type
+ >::type
+ >::type
+ type;
+};
+
+// NOTE: When using boost::function in Boost.Typeof emulation mode, the user
+// has to register boost::functionN instead of boost::function in oder to
+// do TYPEOF(F::operator()). That is confusing, so boost::function is handled
+// separately so it does not require any Boost.Typeof registration at all.
+template<typename F>
+struct functor_type< boost::function<F> > {
+ typedef F type;
+};
+
+// Requires: F is a function type, pointer, reference, or monomorphic functor.
+// Returns: F's function type `result_type (arg1_type, arg2_type, ...)`.
+template<typename F>
+struct function_type {
+ typedef
+ typename boost::mpl::if_<boost::function_types::is_function<F>,
+ boost::mpl::identity<F>
+ ,
+ typename boost::mpl::if_<boost::function_types::
+ is_function_pointer<F>,
+ boost::remove_pointer<F>
+ ,
+ typename boost::mpl::if_<boost::function_types::
+ is_function_reference<F>,
+ boost::remove_reference<F>
+ , // Else, requires that F is a functor.
+ functor_type<F>
+ >::type
+ >::type
+ >::type
+ ::type type;
+};
+
+} } // namespace
+
+#endif // #include guard
+