variadic_templates_tools.hpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2008-2013. Distributed under the Boost
  4. // Software License, Version 1.0. (See accompanying file
  5. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // See http://www.boost.org/libs/container for documentation.
  8. //
  9. //////////////////////////////////////////////////////////////////////////////
  10. #ifndef BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
  11. #define BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
  12. #ifndef BOOST_CONFIG_HPP
  13. # include <boost/config.hpp>
  14. #endif
  15. #if defined(BOOST_HAS_PRAGMA_ONCE)
  16. # pragma once
  17. #endif
  18. #include <boost/container/detail/config_begin.hpp>
  19. #include <boost/container/detail/workaround.hpp>
  20. #include <boost/move/utility_core.hpp>
  21. #include <boost/container/detail/type_traits.hpp>
  22. #include <cstddef> //std::size_t
  23. namespace boost {
  24. namespace container {
  25. namespace dtl {
  26. template<typename... Values>
  27. class tuple;
  28. template<> class tuple<>
  29. {};
  30. template<typename Head, typename... Tail>
  31. class tuple<Head, Tail...>
  32. : private tuple<Tail...>
  33. {
  34. typedef tuple<Tail...> inherited;
  35. public:
  36. tuple()
  37. : inherited(), m_head()
  38. {}
  39. template<class U, class ...Args>
  40. tuple(U &&u, Args && ...args)
  41. : inherited(::boost::forward<Args>(args)...), m_head(::boost::forward<U>(u))
  42. {}
  43. // Construct tuple from another tuple.
  44. template<typename... VValues>
  45. tuple(const tuple<VValues...>& other)
  46. : inherited(other.tail()), m_head(other.head())
  47. {}
  48. template<typename... VValues>
  49. tuple& operator=(const tuple<VValues...>& other)
  50. {
  51. m_head = other.head();
  52. tail() = other.tail();
  53. return this;
  54. }
  55. typename add_reference<Head>::type head() { return m_head; }
  56. typename add_reference<const Head>::type head() const { return m_head; }
  57. inherited& tail() { return *this; }
  58. const inherited& tail() const { return *this; }
  59. protected:
  60. Head m_head;
  61. };
  62. template<typename... Values>
  63. tuple<Values&&...> forward_as_tuple_impl(Values&&... values)
  64. { return tuple<Values&&...>(::boost::forward<Values>(values)...); }
  65. template<int I, typename Tuple>
  66. struct tuple_element;
  67. template<int I, typename Head, typename... Tail>
  68. struct tuple_element<I, tuple<Head, Tail...> >
  69. {
  70. typedef typename tuple_element<I-1, tuple<Tail...> >::type type;
  71. };
  72. template<typename Head, typename... Tail>
  73. struct tuple_element<0, tuple<Head, Tail...> >
  74. {
  75. typedef Head type;
  76. };
  77. template<int I, typename Tuple>
  78. class get_impl;
  79. template<int I, typename Head, typename... Values>
  80. class get_impl<I, tuple<Head, Values...> >
  81. {
  82. typedef typename tuple_element<I-1, tuple<Values...> >::type Element;
  83. typedef get_impl<I-1, tuple<Values...> > Next;
  84. public:
  85. typedef typename add_reference<Element>::type type;
  86. typedef typename add_const_reference<Element>::type const_type;
  87. static type get(tuple<Head, Values...>& t) { return Next::get(t.tail()); }
  88. static const_type get(const tuple<Head, Values...>& t) { return Next::get(t.tail()); }
  89. };
  90. template<typename Head, typename... Values>
  91. class get_impl<0, tuple<Head, Values...> >
  92. {
  93. public:
  94. typedef typename add_reference<Head>::type type;
  95. typedef typename add_const_reference<Head>::type const_type;
  96. static type get(tuple<Head, Values...>& t) { return t.head(); }
  97. static const_type get(const tuple<Head, Values...>& t){ return t.head(); }
  98. };
  99. template<int I, typename... Values>
  100. typename get_impl<I, tuple<Values...> >::type get(tuple<Values...>& t)
  101. { return get_impl<I, tuple<Values...> >::get(t); }
  102. template<int I, typename... Values>
  103. typename get_impl<I, tuple<Values...> >::const_type get(const tuple<Values...>& t)
  104. { return get_impl<I, tuple<Values...> >::get(t); }
  105. ////////////////////////////////////////////////////
  106. // Builds an index_tuple<0, 1, 2, ..., Num-1>, that will
  107. // be used to "unpack" into comma-separated values
  108. // in a function call.
  109. ////////////////////////////////////////////////////
  110. template<std::size_t...> struct index_tuple{ typedef index_tuple type; };
  111. template<class S1, class S2> struct concat_index_tuple;
  112. template<std::size_t... I1, std::size_t... I2>
  113. struct concat_index_tuple<index_tuple<I1...>, index_tuple<I2...>>
  114. : index_tuple<I1..., (sizeof...(I1)+I2)...>{};
  115. template<std::size_t N> struct build_number_seq;
  116. template<std::size_t N>
  117. struct build_number_seq
  118. : concat_index_tuple<typename build_number_seq<N/2>::type
  119. ,typename build_number_seq<N - N/2 >::type
  120. >::type
  121. {};
  122. template<> struct build_number_seq<0> : index_tuple<>{};
  123. template<> struct build_number_seq<1> : index_tuple<0>{};
  124. }}} //namespace boost { namespace container { namespace dtl {
  125. #include <boost/container/detail/config_end.hpp>
  126. #endif //#ifndef BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP