You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
153 lines
4.6 KiB
153 lines
4.6 KiB
////////////////////////////////////////////////////////////////////////////// |
|
// |
|
// (C) Copyright Ion Gaztanaga 2008-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) |
|
// |
|
// See http://www.boost.org/libs/interprocess for documentation. |
|
// |
|
////////////////////////////////////////////////////////////////////////////// |
|
|
|
#ifndef BOOST_INTERPROCESS_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP |
|
#define BOOST_INTERPROCESS_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP |
|
|
|
#if (defined _MSC_VER) && (_MSC_VER >= 1200) |
|
# pragma once |
|
#endif |
|
|
|
#include <boost/interprocess/detail/config_begin.hpp> |
|
#include <boost/interprocess/detail/workaround.hpp> |
|
#include <boost/interprocess/detail/type_traits.hpp> |
|
#include <cstddef> //std::size_t |
|
|
|
namespace boost { |
|
namespace interprocess { |
|
namespace ipcdetail { |
|
|
|
template<typename... Values> |
|
class tuple; |
|
|
|
template<> class tuple<> |
|
{}; |
|
|
|
template<typename Head, typename... Tail> |
|
class tuple<Head, Tail...> |
|
: private tuple<Tail...> |
|
{ |
|
typedef tuple<Tail...> inherited; |
|
|
|
public: |
|
tuple() { } |
|
|
|
// implicit copy-constructor is okay |
|
// Construct tuple from separate arguments. |
|
tuple(typename add_const_reference<Head>::type v, |
|
typename add_const_reference<Tail>::type... vtail) |
|
: inherited(vtail...), m_head(v) |
|
{} |
|
|
|
// Construct tuple from another tuple. |
|
template<typename... VValues> |
|
tuple(const tuple<VValues...>& other) |
|
: m_head(other.head()), inherited(other.tail()) |
|
{} |
|
|
|
template<typename... VValues> |
|
tuple& operator=(const tuple<VValues...>& other) |
|
{ |
|
m_head = other.head(); |
|
tail() = other.tail(); |
|
return this; |
|
} |
|
|
|
typename add_reference<Head>::type head() { return m_head; } |
|
typename add_reference<const Head>::type head() const { return m_head; } |
|
|
|
inherited& tail() { return *this; } |
|
const inherited& tail() const { return *this; } |
|
|
|
protected: |
|
Head m_head; |
|
}; |
|
|
|
|
|
template<typename... Values> |
|
tuple<Values&&...> tie_forward(Values&&... values) |
|
{ return tuple<Values&&...>(values...); } |
|
|
|
template<int I, typename Tuple> |
|
struct tuple_element; |
|
|
|
template<int I, typename Head, typename... Tail> |
|
struct tuple_element<I, tuple<Head, Tail...> > |
|
{ |
|
typedef typename tuple_element<I-1, tuple<Tail...> >::type type; |
|
}; |
|
|
|
template<typename Head, typename... Tail> |
|
struct tuple_element<0, tuple<Head, Tail...> > |
|
{ |
|
typedef Head type; |
|
}; |
|
|
|
template<int I, typename Tuple> |
|
class get_impl; |
|
|
|
template<int I, typename Head, typename... Values> |
|
class get_impl<I, tuple<Head, Values...> > |
|
{ |
|
typedef typename tuple_element<I-1, tuple<Values...> >::type Element; |
|
typedef get_impl<I-1, tuple<Values...> > Next; |
|
|
|
public: |
|
typedef typename add_reference<Element>::type type; |
|
typedef typename add_const_reference<Element>::type const_type; |
|
static type get(tuple<Head, Values...>& t) { return Next::get(t.tail()); } |
|
static const_type get(const tuple<Head, Values...>& t) { return Next::get(t.tail()); } |
|
}; |
|
|
|
template<typename Head, typename... Values> |
|
class get_impl<0, tuple<Head, Values...> > |
|
{ |
|
public: |
|
typedef typename add_reference<Head>::type type; |
|
typedef typename add_const_reference<Head>::type const_type; |
|
static type get(tuple<Head, Values...>& t) { return t.head(); } |
|
static const_type get(const tuple<Head, Values...>& t){ return t.head(); } |
|
}; |
|
|
|
template<int I, typename... Values> |
|
typename get_impl<I, tuple<Values...> >::type get(tuple<Values...>& t) |
|
{ return get_impl<I, tuple<Values...> >::get(t); } |
|
|
|
template<int I, typename... Values> |
|
typename get_impl<I, tuple<Values...> >::const_type get(const tuple<Values...>& t) |
|
{ return get_impl<I, tuple<Values...> >::get(t); } |
|
|
|
//////////////////////////////////////////////////// |
|
// Builds an index_tuple<0, 1, 2, ..., Num-1>, that will |
|
// be used to "unpack" into comma-separated values |
|
// in a function call. |
|
//////////////////////////////////////////////////// |
|
|
|
template<int... Indexes> |
|
struct index_tuple{}; |
|
|
|
template<std::size_t Num, typename Tuple = index_tuple<> > |
|
struct build_number_seq; |
|
|
|
template<std::size_t Num, int... Indexes> |
|
struct build_number_seq<Num, index_tuple<Indexes...> > |
|
: build_number_seq<Num - 1, index_tuple<Indexes..., sizeof...(Indexes)> > |
|
{}; |
|
|
|
template<int... Indexes> |
|
struct build_number_seq<0, index_tuple<Indexes...> > |
|
{ typedef index_tuple<Indexes...> type; }; |
|
|
|
|
|
}}} //namespace boost { namespace interprocess { namespace ipcdetail { |
|
|
|
#include <boost/interprocess/detail/config_end.hpp> |
|
|
|
#endif //#ifndef BOOST_INTERPROCESS_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
|
|
|