summaryrefslogtreecommitdiff
path: root/boost/context/detail
diff options
context:
space:
mode:
Diffstat (limited to 'boost/context/detail')
-rw-r--r--boost/context/detail/apply.hpp55
-rw-r--r--boost/context/detail/config.hpp59
-rw-r--r--boost/context/detail/disable_overload.hpp40
-rw-r--r--boost/context/detail/exception.hpp36
-rw-r--r--boost/context/detail/exchange.hpp36
-rw-r--r--boost/context/detail/fcontext.hpp46
-rw-r--r--boost/context/detail/index_sequence.hpp72
-rw-r--r--boost/context/detail/invoke.hpp58
-rw-r--r--boost/context/detail/tuple.hpp129
9 files changed, 466 insertions, 65 deletions
diff --git a/boost/context/detail/apply.hpp b/boost/context/detail/apply.hpp
new file mode 100644
index 0000000000..54db844b9e
--- /dev/null
+++ b/boost/context/detail/apply.hpp
@@ -0,0 +1,55 @@
+
+// Copyright Oliver Kowalke 2014.
+// 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_CONTEXT_DETAIL_APPLY_H
+#define BOOST_CONTEXT_DETAIL_APPLY_H
+
+#include <functional>
+#include <tuple>
+#include <type_traits>
+#include <utility>
+
+#include <boost/config.hpp>
+
+#include <boost/context/detail/config.hpp>
+#include <boost/context/detail/invoke.hpp>
+#include <boost/context/detail/index_sequence.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace context {
+namespace detail {
+
+template< typename Fn, typename Tpl, std::size_t ... I >
+auto
+apply_impl( Fn && fn, Tpl && tpl, index_sequence< I ... >)
+ -> decltype( invoke( std::forward< Fn >( fn), std::get< I >( std::forward< Tpl >( tpl) ) ... ) )
+{
+ return invoke( std::forward< Fn >( fn), std::get< I >( std::forward< Tpl >( tpl) ) ... );
+}
+
+template< typename Fn, typename Tpl >
+auto
+apply( Fn && fn, Tpl && tpl)
+ -> decltype( apply_impl( std::forward< Fn >( fn),
+ std::forward< Tpl >( tpl),
+ make_index_sequence< std::tuple_size< typename std::decay< Tpl >::type >::value >{}) )
+{
+ return apply_impl( std::forward< Fn >( fn),
+ std::forward< Tpl >( tpl),
+ make_index_sequence< std::tuple_size< typename std::decay< Tpl >::type >::value >{});
+}
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+#include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_CONTEXT_DETAIL_APPLY_H
diff --git a/boost/context/detail/config.hpp b/boost/context/detail/config.hpp
index 0d5fa757fa..84dd238100 100644
--- a/boost/context/detail/config.hpp
+++ b/boost/context/detail/config.hpp
@@ -57,32 +57,51 @@
# define BOOST_CONTEXT_SEGMENTS 10
#endif
-#undef BOOST_CONTEXT_NO_EXECUTION_CONTEXT
-#if defined(BOOST_NO_CXX11_CONSTEXPR) || \
- defined(BOOST_NO_CXX11_DECLTYPE) || \
- defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) || \
- defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) || \
+
+#define BOOST_CONTEXT_NO_CXX14_INTEGER_SEQUENCE
+// use rd6 macros for std::integer_sequence
+#if defined(__cpp_lib_integer_sequence) && __cpp_lib_integer_sequence >= 201304
+# undef BOOST_CONTEXT_NO_CXX14_INTEGER_SEQUENCE
+#endif
+// workaroud: MSVC 14 does not provide macros to test for compile-time integer sequence
+#if _MSC_VER > 1800 // _MSC_VER == 1800 -> MS Visual Studio 2013
+# undef BOOST_CONTEXT_NO_INDEX_SEQUENCE
+#endif
+// workaround: Xcode clang feature detection
+#if ! defined(__cpp_lib_integer_sequence) && __cpp_lib_integer_sequence >= 201304
+# if _LIBCPP_STD_VER > 11
+# undef BOOST_CONTEXT_NO_CXX14_INTEGER_SEQUENCE
+# endif
+#endif
+
+// workaroud: MSVC 14 does support constexpr
+#if _MSC_VER > 1800 // _MSC_VER == 1800 -> MS Visual Studio 2013
+# undef BOOST_NO_CXX11_CONSTEXPR
+#endif
+
+#undef BOOST_CONTEXT_NO_CXX11
+#if defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) || \
+ defined(BOOST_NO_CXX11_CONSTEXPR) || \
+ defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || \
+ defined(BOOST_NO_CXX11_FINAL) || \
defined(BOOST_NO_CXX11_HDR_TUPLE) || \
- defined(BOOST_NO_CXX11_LAMBDAS) || \
defined(BOOST_NO_CXX11_NOEXCEPT) || \
defined(BOOST_NO_CXX11_NULLPTR) || \
- defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) || \
defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || \
- defined(BOOST_NO_CXX11_VARIADIC_MACROS) || \
+ defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) || \
+ defined(BOOST_NO_CXX11_UNIFIED_INITIALISATION_SYNTAX) || \
defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || \
- defined(BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES) || \
- ! defined(__cpp_lib_integer_sequence) && __cpp_lib_integer_sequence < 201304
-# define BOOST_CONTEXT_NO_EXECUTION_CONTEXT
-#endif
-// workaroud: MSVC 14 does not provide macros to test for compile-time integer sequence
-#if _MSC_VER > 1800 // _MSC_VER == 1800 -> MS Visual Studio 2013
-# undef BOOST_CONTEXT_NO_EXECUTION_CONTEXT
+ defined(BOOST_NO_HDR_ATOMIC) || \
+ defined(BOOST_NO_HDR_TUPLE)
+# define BOOST_CONTEXT_NO_CXX11
#endif
-// workaround: Xcode clang feature detection
-#if ! defined(__cpp_lib_integer_sequence) && __cpp_lib_integer_sequence < 201304
-# if _LIBCPP_STD_VER > 11
-# undef BOOST_CONTEXT_NO_EXECUTION_CONTEXT
-# endif
+
+#if ! defined(BOOST_EXECUTION_CONTEXT)
+# if defined(BOOST_USE_SEGMENTED_STACKS)
+# define BOOST_EXECUTION_CONTEXT 1
+# else
+# define BOOST_EXECUTION_CONTEXT 2
+# endif
#endif
#endif // BOOST_CONTEXT_DETAIL_CONFIG_H
diff --git a/boost/context/detail/disable_overload.hpp b/boost/context/detail/disable_overload.hpp
new file mode 100644
index 0000000000..c88f916e39
--- /dev/null
+++ b/boost/context/detail/disable_overload.hpp
@@ -0,0 +1,40 @@
+
+// Copyright Oliver Kowalke 2014.
+// 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_CONTEXT_DETAIL_DISABLE_OVERLOAD_H
+#define BOOST_CONTEXT_DETAIL_DISABLE_OVERLOAD_H
+
+#include <type_traits>
+
+#include <boost/config.hpp>
+
+#include <boost/context/detail/config.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace context {
+namespace detail {
+
+// http://ericniebler.com/2013/08/07/universal-references-and-the-copy-constructo/
+template< typename X, typename Y >
+using disable_overload =
+ typename std::enable_if<
+ ! std::is_base_of<
+ X,
+ typename std::decay< Y >::type
+ >::value
+ >::type;
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+#include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_CONTEXT_DETAIL_DISABLE_OVERLOAD_H
diff --git a/boost/context/detail/exception.hpp b/boost/context/detail/exception.hpp
new file mode 100644
index 0000000000..8ffff6780a
--- /dev/null
+++ b/boost/context/detail/exception.hpp
@@ -0,0 +1,36 @@
+
+// Copyright Oliver Kowalke 2014.
+// 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_CONTEXT_DETAIL_EXCEPTION_H
+#define BOOST_CONTEXT_DETAIL_EXCEPTION_H
+
+#include <boost/config.hpp>
+
+#include <boost/context/detail/fcontext.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace context {
+namespace detail {
+
+struct forced_unwind {
+ fcontext_t fctx;
+
+ forced_unwind( fcontext_t fctx_) :
+ fctx( fctx_) {
+ }
+};
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+#include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_CONTEXT_DETAIL_EXCEPTION_H
diff --git a/boost/context/detail/exchange.hpp b/boost/context/detail/exchange.hpp
new file mode 100644
index 0000000000..c5ee91284e
--- /dev/null
+++ b/boost/context/detail/exchange.hpp
@@ -0,0 +1,36 @@
+
+// Copyright Oliver Kowalke 2014.
+// 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_CONTEXT_DETAIL_EXCHANGE_H
+#define BOOST_CONTEXT_DETAIL_EXCHANGE_H
+
+#include <algorithm>
+#include <utility>
+
+#include <boost/config.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace context {
+namespace detail {
+
+template< typename T, typename U = T >
+T exchange( T & t, U && nv) {
+ T ov = std::move( t);
+ t = std::forward< U >( nv);
+ return ov;
+}
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+#include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_CONTEXT_DETAIL_EXCHANGE_H
diff --git a/boost/context/detail/fcontext.hpp b/boost/context/detail/fcontext.hpp
new file mode 100644
index 0000000000..00cb24d941
--- /dev/null
+++ b/boost/context/detail/fcontext.hpp
@@ -0,0 +1,46 @@
+
+// Copyright Oliver Kowalke 2009.
+// 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_CONTEXT_DETAIL_FCONTEXT_H
+#define BOOST_CONTEXT_DETAIL_FCONTEXT_H
+
+#include <boost/config.hpp>
+#include <boost/cstdint.hpp>
+
+#include <boost/context/detail/config.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace context {
+namespace detail {
+
+typedef void* fcontext_t;
+
+struct transfer_t {
+ fcontext_t fctx;
+ void * data;
+};
+
+extern "C" BOOST_CONTEXT_DECL
+transfer_t BOOST_CONTEXT_CALLDECL jump_fcontext( fcontext_t const to, void * vp);
+extern "C" BOOST_CONTEXT_DECL
+fcontext_t BOOST_CONTEXT_CALLDECL make_fcontext( void * sp, std::size_t size, void (* fn)( transfer_t) );
+
+// based on an idea of Giovanni Derreta
+extern "C" BOOST_CONTEXT_DECL
+transfer_t BOOST_CONTEXT_CALLDECL ontop_fcontext( fcontext_t const to, void * vp, transfer_t (* fn)( transfer_t) );
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_CONTEXT_DETAIL_FCONTEXT_H
+
diff --git a/boost/context/detail/index_sequence.hpp b/boost/context/detail/index_sequence.hpp
new file mode 100644
index 0000000000..2d484ba062
--- /dev/null
+++ b/boost/context/detail/index_sequence.hpp
@@ -0,0 +1,72 @@
+
+// Copyright Oliver Kowalke 2014.
+// 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_CONTEXT_DETAIL_INDEX_SEQUENCE_H
+#define BOOST_CONTEXT_DETAIL_INDEX_SEQUENCE_H
+
+#include <cstddef>
+
+#include <boost/config.hpp>
+
+#include <boost/context/detail/config.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace context {
+namespace detail {
+
+#if ! defined(BOOST_CONTEXT_NO_CXX14_INTEGER_SEQUENCE)
+template< std::size_t ... I >
+using index_sequence = std::index_sequence< I ... >;
+template< std::size_t I >
+using make_index_sequence = std::make_index_sequence< I >;
+template< typename ... T >
+using index_sequence_for = std::index_sequence_for< T ... >;
+#else
+//http://stackoverflow.com/questions/17424477/implementation-c14-make-integer-sequence
+
+template< std::size_t ... I >
+struct index_sequence {
+ using type = index_sequence;
+ using value_type = std::size_t;
+ static constexpr std::size_t size() {
+ return sizeof ... (I);
+ }
+};
+
+template< typename Seq1, typename Seq2 >
+struct concat_sequence;
+
+template< std::size_t ... I1, std::size_t ... I2 >
+struct concat_sequence< index_sequence< I1 ... >, index_sequence< I2 ... > > : public index_sequence< I1 ..., (sizeof ... (I1)+I2) ... > {
+};
+
+template< std::size_t I >
+struct make_index_sequence : public concat_sequence< typename make_index_sequence< I/2 >::type,
+ typename make_index_sequence< I-I/2 >::type > {
+};
+
+template<>
+struct make_index_sequence< 0 > : public index_sequence<> {
+};
+template<>
+struct make_index_sequence< 1 > : public index_sequence< 0 > {
+};
+
+template< typename ... T >
+using index_sequence_for = make_index_sequence< sizeof ... (T) >;
+#endif
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+#include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_CONTEXT_DETAIL_INDEX_SEQUENCE_H
diff --git a/boost/context/detail/invoke.hpp b/boost/context/detail/invoke.hpp
index f63d22c3ff..5ec54800e3 100644
--- a/boost/context/detail/invoke.hpp
+++ b/boost/context/detail/invoke.hpp
@@ -13,6 +13,8 @@
#include <boost/config.hpp>
+#include <boost/context/detail/config.hpp>
+
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
@@ -21,61 +23,27 @@ namespace boost {
namespace context {
namespace detail {
-# if _MSC_VER > 1800
+#if _MSC_VER > 1800
using std::invoke;
-# else
-template< typename Fn, typename ... Args >
-typename std::enable_if<
- ( ! std::is_member_pointer< Fn >::value &&
- ! std::is_function< Fn >::value &&
- ! std::is_function< typename std::remove_pointer< Fn >::type >::value
- ),
- typename std::result_of< Fn( Args ... ) >::type
->::type
-invoke( Fn & fn, Args && ... args) {
- return fn( std::forward< Args >( args) ... );
-}
-
+#else
template< typename Fn, typename ... Args >
typename std::enable_if<
- ( std::is_member_pointer< Fn >::value &&
- ! std::is_function< Fn >::value &&
- ! std::is_function< typename std::remove_pointer< Fn >::type >::value
- ),
- typename std::result_of< Fn( Args ... ) >::type
+ std::is_member_pointer< typename std::decay< Fn >::type >::value,
+ typename std::result_of< Fn &&( Args && ... ) >::type
>::type
-invoke( Fn & fn, Args && ... args) {
- return std::mem_fn( fn)( std::forward< Args >( args) ... );
+invoke( Fn && fn, Args && ... args) {
+ return std::mem_fn( fn)( std::forward< Args >( args) ... );
}
template< typename Fn, typename ... Args >
typename std::enable_if<
- ( std::is_pointer< Fn >::value &&
- std::is_function< typename std::remove_pointer< Fn >::type >::value
- ),
- typename std::result_of< Fn( Args ... ) >::type
+ ! std::is_member_pointer< typename std::decay< Fn >::type >::value,
+ typename std::result_of< Fn &&( Args && ... ) >::type
>::type
-invoke( Fn fn, Args && ... args) {
- return fn( std::forward< Args >( args) ... );
-}
-# endif
-
-template< typename Fn, typename Tpl, std::size_t... I >
-decltype( auto) do_invoke( Fn && fn, Tpl && tpl, std::index_sequence< I ... >) {
- return invoke( fn,
- // std::tuple_element<> does not perfect forwarding
- std::forward< decltype( std::get< I >( std::declval< typename std::decay< Tpl >::type >() ) ) >(
- std::get< I >( std::forward< typename std::decay< Tpl >::type >( tpl) ) ) ... );
-}
-
-
-template< typename Fn, typename Tpl >
-decltype( auto) do_invoke( Fn && fn, Tpl && tpl) {
- constexpr auto Size = std::tuple_size< typename std::decay< Tpl >::type >::value;
- return do_invoke( std::forward< Fn >( fn),
- std::forward< Tpl >( tpl),
- std::make_index_sequence< Size >{});
+invoke( Fn && fn, Args && ... args) {
+ return std::forward< Fn >( fn)( std::forward< Args >( args) ... );
}
+#endif
}}}
diff --git a/boost/context/detail/tuple.hpp b/boost/context/detail/tuple.hpp
new file mode 100644
index 0000000000..e1b2f867a7
--- /dev/null
+++ b/boost/context/detail/tuple.hpp
@@ -0,0 +1,129 @@
+
+// Copyright Oliver Kowalke 2014.
+// 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_CONTEXT_DETAIL_TUPLE_H
+#define BOOST_CONTEXT_DETAIL_TUPLE_H
+
+#include <tuple>
+#include <utility>
+
+#include <boost/config.hpp>
+
+#include <boost/context/detail/config.hpp>
+#include <boost/context/detail/index_sequence.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace context {
+namespace detail {
+
+template< typename ... S, typename ... T, std::size_t ... I >
+void
+head_impl( std::tuple< S ... > & s,
+ std::tuple< T ... > & t, index_sequence< I ... >) {
+ t = std::tuple< T ... >{ std::get< I >( s) ... };
+}
+
+template< typename ... S, typename ... T, std::size_t ... I >
+void
+head_impl( std::tuple< S ... > && s,
+ std::tuple< T ... > & t, index_sequence< I ... >) {
+ t = std::tuple< T ... >{ std::get< I >( std::move( s) ) ... };
+}
+
+template< typename ... S, std::size_t ... I1, typename ... T, std::size_t ... I2 >
+void
+tail_impl( std::tuple< S ... > & s, index_sequence< I1 ... >,
+ std::tuple< T ... > & t, index_sequence< I2 ... >) {
+ constexpr std::size_t Idx = (sizeof...(I1)) - (sizeof...(I2));
+ t = std::tuple< T ... >{ std::get< (Idx + I2) >( s) ... };
+}
+
+template< typename ... S, std::size_t ... I1, typename ... T, std::size_t ... I2 >
+void
+tail_impl( std::tuple< S ... > && s, index_sequence< I1 ... >,
+ std::tuple< T ... > & t, index_sequence< I2 ... >) {
+ constexpr std::size_t Idx = (sizeof...(I1)) - (sizeof...(I2));
+ t = std::tuple< T ... >{ std::get< (Idx + I2) >( std::move( s) ) ... };
+}
+
+template< typename ... T >
+class tuple_head;
+
+template< typename ... T >
+class tuple_head< std::tuple< T ... > > {
+private:
+ std::tuple< T ... > & t_;
+
+public:
+ tuple_head( std::tuple< T ... > & t) noexcept :
+ t_( t) {
+ }
+
+ template< typename ... S >
+ void operator=( std::tuple< S ... > & s) {
+ static_assert((sizeof...(T)) <= (sizeof...(S)), "invalid tuple size");
+ head_impl( s,
+ t_, index_sequence_for< T ... >{} );
+ }
+ template< typename ... S >
+ void operator=( std::tuple< S ... > && s) {
+ static_assert((sizeof...(T)) <= (sizeof...(S)), "invalid tuple size");
+ head_impl( std::move( s),
+ t_, index_sequence_for< T ... >{} );
+ }
+};
+
+template< typename ... T >
+class tuple_tail;
+
+template< typename ... T >
+class tuple_tail< std::tuple< T ... > > {
+private:
+ std::tuple< T ... > & t_;
+
+public:
+ tuple_tail( std::tuple< T ... > & t) noexcept :
+ t_( t) {
+ }
+
+ template< typename ... S >
+ void operator=( std::tuple< S ... > & s) {
+ static_assert((sizeof...(T)) <= (sizeof...(S)), "invalid tuple size");
+ tail_impl( s, index_sequence_for< S ... >{},
+ t_, index_sequence_for< T ... >{} );
+ }
+
+ template< typename ... S >
+ void operator=( std::tuple< S ... > && s) {
+ static_assert((sizeof...(T)) <= (sizeof...(S)), "invalid tuple size");
+ tail_impl( std::move( s), index_sequence_for< S ... >{},
+ t_, index_sequence_for< T ... >{} );
+ }
+};
+
+template< typename ... T >
+detail::tuple_head< std::tuple< T ... > >
+head( std::tuple< T ... > & tpl) {
+ return tuple_head< std::tuple< T ... > >{ tpl };
+}
+
+template< typename ... T >
+detail::tuple_tail< std::tuple< T ... > >
+tail( std::tuple< T ... > & tpl) {
+ return tuple_tail< std::tuple< T ... > >{ tpl };
+}
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+#include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_CONTEXT_DETAIL_TUPLE_H