Imported existing code
This commit is contained in:
170
libraries/include/boost/coroutine/tuple_traits.hpp
Normal file
170
libraries/include/boost/coroutine/tuple_traits.hpp
Normal file
@@ -0,0 +1,170 @@
|
||||
// Copyright (c) 2006, Giovanni P. Deretta
|
||||
//
|
||||
// This code may be used under either of the following two licences:
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE. OF SUCH DAMAGE.
|
||||
//
|
||||
// Or:
|
||||
//
|
||||
// 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_COROUTINE_TUPLE_TRAITS_HPP_20060613
|
||||
#define BOOST_COROUTINE_TUPLE_TRAITS_HPP_20060613
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/facilities/intercept.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/mpl/eval_if.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/coroutine/detail/arg_max.hpp>
|
||||
|
||||
namespace boost { namespace coroutines {
|
||||
namespace detail {
|
||||
/*
|
||||
* NOTE & FIXME: coroutine_traits relies on the fact that we can construct a
|
||||
* boost::tuple specifing more arguments of type null_type than
|
||||
* required without generating an error. This is an undocumented
|
||||
* 'feature' and doesn't actually work for nullary tuples,
|
||||
* so we need to detect this case and handle it with tuple_workaround.
|
||||
* If ever boost::tuple is changed (for example by switching to fusion)
|
||||
* tuple_workaround should be used in all cases to handle extra
|
||||
* parameters.
|
||||
* The real solution would be to have an internal tuple
|
||||
* type that derives from boost::tuple and handles all cases we care about.
|
||||
* Or better, just use Boost.Fusion.
|
||||
* In general the code in this file needs to be put in a better shape,
|
||||
* eliminating all corner cases.
|
||||
*/
|
||||
|
||||
/*
|
||||
* A boost::tuple<> is not constructible from an arbitrary
|
||||
* number of null_types (while non nullary tuples are).
|
||||
* This class takes care of this assimmetry.
|
||||
*/
|
||||
struct tuple_workaround : boost::tuple<> {
|
||||
# define BOOST_COROUTINE_arg_null_typecr(z, n, unused)\
|
||||
const boost::tuples::null_type& \
|
||||
/**/
|
||||
|
||||
tuple_workaround
|
||||
(BOOST_PP_ENUM
|
||||
(BOOST_COROUTINE_ARG_MAX,
|
||||
BOOST_COROUTINE_arg_null_typecr,
|
||||
~)){}
|
||||
|
||||
tuple_workaround(const tuple_workaround&) {}
|
||||
tuple_workaround() {}
|
||||
# undef BOOST_COROUTINE_arg_null_typecr
|
||||
};
|
||||
} /* detail */
|
||||
|
||||
// All tuple traits must be derived from this
|
||||
// class to be correctly recognized.
|
||||
struct tuple_traits_tag {};
|
||||
|
||||
template<typename T>
|
||||
struct get_length {
|
||||
enum { length = T::length };
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct is_nullary : boost::mpl::bool_<boost::tuples::length<T>::value == 0> { };
|
||||
|
||||
template<typename T>
|
||||
struct is_singular : boost::mpl::bool_<boost::tuples::length<T>::value == 1> { };
|
||||
|
||||
// Given a tuple_traits, makes a tuple of it
|
||||
// Simply returns the internal tuple type, unless
|
||||
// the tuple is nullary, then apply the nullary tuple workaround
|
||||
template<typename T>
|
||||
struct make_as_tuple :
|
||||
boost::mpl::if_<
|
||||
is_nullary<T>,
|
||||
detail::tuple_workaround,
|
||||
T
|
||||
> {};
|
||||
|
||||
// Used to implement the next metafunction,
|
||||
// Splitted in two parts to satisfy the compiler.
|
||||
template<typename T>
|
||||
struct step_2 :
|
||||
boost::mpl::eval_if<
|
||||
is_singular<T>,
|
||||
boost::tuples::element<0, typename make_as_tuple<T>::type >,
|
||||
boost::mpl::identity<typename make_as_tuple<T>::type> > { };
|
||||
|
||||
// Given a trait class return the internal tuple type modified
|
||||
// as a return value.
|
||||
// The algorithm is as follow:
|
||||
// - If the tuple is nullary returns 'void'.
|
||||
// - If it singular returns the first type
|
||||
// - Else return the tuple itself.
|
||||
template<typename T>
|
||||
struct make_result_type :
|
||||
boost::mpl::eval_if<
|
||||
is_nullary<T>,
|
||||
boost::mpl::identity<void>,
|
||||
step_2<T> > { };
|
||||
|
||||
template<
|
||||
BOOST_PP_ENUM_BINARY_PARAMS
|
||||
(BOOST_COROUTINE_ARG_MAX,
|
||||
typename T,
|
||||
= boost::tuples::null_type BOOST_PP_INTERCEPT)>
|
||||
struct tuple_traits : tuple_traits_tag {
|
||||
public:
|
||||
|
||||
// This is the straightforward boost::tuple trait
|
||||
// derived from the argument list. It is not
|
||||
// directly used in all cases.
|
||||
typedef boost::tuple
|
||||
<BOOST_PP_ENUM_PARAMS
|
||||
(BOOST_COROUTINE_ARG_MAX, T)> internal_tuple_type;
|
||||
|
||||
// FIXME: Currently coroutine code does not use this typedef in all cases
|
||||
// and expect it to be equal to boost::tuples::null_type
|
||||
typedef boost::tuples::null_type null_type;
|
||||
enum {length = boost::tuples::length<internal_tuple_type>::value};
|
||||
|
||||
// Return the element at the Indext'th position in the typelist.
|
||||
// If the index is not less than the tuple length, it returns
|
||||
// null_type.
|
||||
template<int Index>
|
||||
struct at :
|
||||
boost::mpl::eval_if_c<
|
||||
Index <
|
||||
boost::tuples::length<typename tuple_traits::internal_tuple_type>::value,
|
||||
boost::tuples::element<Index, typename tuple_traits::internal_tuple_type>,
|
||||
boost::mpl::identity<typename tuple_traits::null_type> >{};
|
||||
|
||||
typedef typename make_as_tuple<internal_tuple_type>::type
|
||||
as_tuple;
|
||||
|
||||
typedef typename make_result_type<internal_tuple_type>::type as_result;
|
||||
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct is_tuple_traits : boost::is_base_of<tuple_traits_tag, T> {};
|
||||
} }
|
||||
#endif
|
||||
Reference in New Issue
Block a user