Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r81067 - sandbox/variadic_templates/sandbox/slim/test
From: cppljevans_at_[hidden]
Date: 2012-10-26 08:54:40


Author: cppljevans
Date: 2012-10-26 08:54:38 EDT (Fri, 26 Oct 2012)
New Revision: 81067
URL: http://svn.boost.org/trac/boost/changeset/81067

Log:
Added tuple implementations from boostcon 2012:

https://github.com/ericniebler/home/tree/master/src/tuple

after extracting relevant parts into tuple_impl_bcon12*.hpp
files.

Added:
   sandbox/variadic_templates/sandbox/slim/test/tuple.benchmark.mini.time.txt (contents, props changed)
   sandbox/variadic_templates/sandbox/slim/test/tuple.test.cpp (contents, props changed)
   sandbox/variadic_templates/sandbox/slim/test/tuple_impl_bcon12_horizontal.hpp (contents, props changed)
   sandbox/variadic_templates/sandbox/slim/test/tuple_impl_bcon12_vertical.hpp (contents, props changed)
Text files modified:
   sandbox/variadic_templates/sandbox/slim/test/Makefile | 13 +++++++------
   sandbox/variadic_templates/sandbox/slim/test/macros.benchmark.pp.hpp | 1 -
   sandbox/variadic_templates/sandbox/slim/test/tuple.benchmark.mini.cpp | 8 ++++----
   sandbox/variadic_templates/sandbox/slim/test/tuple_benchmark_run.py | 15 ++++++++++-----
   4 files changed, 21 insertions(+), 16 deletions(-)

Modified: sandbox/variadic_templates/sandbox/slim/test/Makefile
==============================================================================
--- sandbox/variadic_templates/sandbox/slim/test/Makefile (original)
+++ sandbox/variadic_templates/sandbox/slim/test/Makefile 2012-10-26 08:54:38 EDT (Fri, 26 Oct 2012)
@@ -1,23 +1,24 @@
 MAIN=test
 BENCHMARK=mini
+BENCHMARK=tree_builder
 MAIN=tuple.benchmark.$(BENCHMARK)
+MAIN=tuple.test
 MEASURE=time
 THISFILE=Makefile
 PYTHON=python3.1
 
+HOW=gcc4_8_20120624
+#HOW=clangxx_rel
 DIR.root := $(shell dirup_dir_file.pl $(PWD) root.imk)
 include $(DIR.root)/root.imk
 #include compiler_macros.imk
 
-HOW=gcc4_8n
-HOW=clangxx_rel
-
 HOWS=gcc4_8n clangxx
 
 SLIM_DIR=../slim/include
 #INCS:= -I$(SLIM_DIR) $(INCS)
 
-BFLAGS=-DTUPLE_SIZE=4 -DLAST_LESS=2 -DTUPLE_IMPL=tuple_impl_std.hpp -DTUPLE_CHUNK=4
+BFLAGS=-DTUPLE_SIZE=4 -DLAST_LESS=2 -DTUPLE_IMPL=tuple_impl_bcon12_vertical.hpp -DTUPLE_CHUNK=4
 BFNAME:=$(shell ./flags2filename.pl -S $(BFLAGS))
 PROF_BASE=$(MAIN).$(HOW).$(BFNAME)
 COMPILER.clangxx_ins-rt=$(PATH.llvm.top)/llvm/projects/compiler-rt
@@ -141,6 +142,6 @@
 echo:
         @echo "SHELL="$(SHELL)
 
-.PHONY: python
-python:
+.PHONY: benchmark_run
+benchmark_run:
         $(PYTHON) tuple_benchmark_run.py

Modified: sandbox/variadic_templates/sandbox/slim/test/macros.benchmark.pp.hpp
==============================================================================
--- sandbox/variadic_templates/sandbox/slim/test/macros.benchmark.pp.hpp (original)
+++ sandbox/variadic_templates/sandbox/slim/test/macros.benchmark.pp.hpp 2012-10-26 08:54:38 EDT (Fri, 26 Oct 2012)
@@ -1,7 +1,6 @@
 #if !defined(TUPLE_SIZE)
   //This only used when not running several benchmarks where
   //macro values are set on command line with -DMACRO=VALUE.
- //See tuple.benchmark.mk.
   #define TUPLE_IMPL tuple_impl_horizontal.hpp
     //TUPLE_TEST_IMPL selects the tuple implementation method.
     //TUPLE_TEST_VERTICAL selects the preprocessor generated

Modified: sandbox/variadic_templates/sandbox/slim/test/tuple.benchmark.mini.cpp
==============================================================================
--- sandbox/variadic_templates/sandbox/slim/test/tuple.benchmark.mini.cpp (original)
+++ sandbox/variadic_templates/sandbox/slim/test/tuple.benchmark.mini.cpp 2012-10-26 08:54:38 EDT (Fri, 26 Oct 2012)
@@ -45,11 +45,11 @@
 };
 
 template<int I,int J, int Max, typename... Args>
-struct make_tuple:
- make_tuple<I,J,Max-1,int_value<I*TUPLE_SIZE*TUPLE_SIZE+J*TUPLE_SIZE+Max>,Args...>
+struct mk_tuple_col_row:
+ mk_tuple_col_row<I,J,Max-1,int_value<I*TUPLE_SIZE*TUPLE_SIZE+J*TUPLE_SIZE+Max>,Args...>
 {};
 template<int I,int J, typename... Args>
-struct make_tuple<I,J,0, Args...>
+struct mk_tuple_col_row<I,J,0, Args...>
 {
         typedef tuple_bench<Args...> type;
 };
@@ -63,7 +63,7 @@
 struct test_row
 {
  private:
- typedef typename make_tuple<I, J, TUPLE_SIZE>::type tuple_type;
+ typedef typename mk_tuple_col_row<I, J, TUPLE_SIZE>::type tuple_type;
 
         template<int K>
         static int at_test(tuple_type& t,int_key<K>)

Added: sandbox/variadic_templates/sandbox/slim/test/tuple.benchmark.mini.time.txt
==============================================================================
--- (empty file)
+++ sandbox/variadic_templates/sandbox/slim/test/tuple.benchmark.mini.time.txt 2012-10-26 08:54:38 EDT (Fri, 26 Oct 2012)
@@ -0,0 +1,72 @@
+compiler= clangxx
+version={
+clang version 3.2 (trunk 165317)
+Target: x86_64-unknown-linux-gnu
+Thread model: posix
+compiler_exe= /home/evansl/download/llvm/svn/build/Release/bin/clang
+}
+['compiler', 'TUPLE_IMPL', 'TUPLE_SIZE', 'LAST_LESS', 'TUPLE_CHUNK']
+['clangxx', 'horizontal', 10, 4, -1]
+{
+user:0.26 system:0.00 elapsed:0.25
+}
+['clangxx', 'horizontal', 20, 4, -1]
+{
+user:0.42 system:0.06 elapsed:0.47
+}
+['clangxx', 'horizontal', 30, 4, -1]
+{
+user:0.60 system:0.10 elapsed:0.69
+}
+['clangxx', 'horizontal', 40, 4, -1]
+{
+user:0.86 system:0.08 elapsed:0.93
+}
+['clangxx', 'bcon12_horizontal', 10, 4, -1]
+{
+user:0.53 system:0.03 elapsed:0.55
+}
+['clangxx', 'bcon12_horizontal', 20, 4, -1]
+{
+user:0.75 system:0.08 elapsed:0.82
+}
+['clangxx', 'bcon12_horizontal', 30, 4, -1]
+{
+user:1.00 system:0.11 elapsed:1.10
+}
+['clangxx', 'bcon12_horizontal', 40, 4, -1]
+{
+user:1.30 system:0.11 elapsed:1.40
+}
+['clangxx', 'vertical', 10, 4, 10]
+{
+user:0.24 system:0.04 elapsed:0.33
+}
+['clangxx', 'vertical', 20, 4, 10]
+{
+user:0.40 system:0.02 elapsed:0.41
+}
+['clangxx', 'vertical', 30, 4, 10]
+{
+user:0.56 system:0.05 elapsed:0.60
+}
+['clangxx', 'vertical', 40, 4, 10]
+{
+user:0.74 system:0.07 elapsed:0.80
+}
+['clangxx', 'bcon12_vertical', 10, 4, -1]
+{
+user:0.45 system:0.05 elapsed:0.49
+}
+['clangxx', 'bcon12_vertical', 20, 4, -1]
+{
+user:0.63 system:0.04 elapsed:0.66
+}
+['clangxx', 'bcon12_vertical', 30, 4, -1]
+{
+user:0.76 system:0.11 elapsed:0.86
+}
+['clangxx', 'bcon12_vertical', 40, 4, -1]
+{
+user:0.98 system:0.08 elapsed:1.05
+}

Added: sandbox/variadic_templates/sandbox/slim/test/tuple.test.cpp
==============================================================================
--- (empty file)
+++ sandbox/variadic_templates/sandbox/slim/test/tuple.test.cpp 2012-10-26 08:54:38 EDT (Fri, 26 Oct 2012)
@@ -0,0 +1,88 @@
+//Acknowlegements:
+// The following code was adapted from part of the code in
+// https://github.com/ericniebler/home/blob/master/src/tuple/unrolled_tuple.hpp
+//ChangeLog:
+// 2012-10-26 LJ Evans
+// 1) Copied the code after the line:
+// #ifdef TEST
+// in the above mentioned unrolled_tuple.hpp file.
+// 2) Added the boostpp #includes.
+// 3) Used the boostpp stringize to #include the tuple implementation code
+// named by a macro.
+//
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 2012 Eric Niebler.
+// 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)
+//
+#include <boost/preprocessor/stringize.hpp>
+#ifndef TUPLE_IMPL
+#define TUPLE_IMPL tuple_impl_bcon12_vertical.hpp
+#endif
+#include BOOST_PP_STRINGIZE(TUPLE_IMPL)
+
+#include <cstdio>
+//////////////////////////////////////////////////////
+//{copied from unrolled_tuple.hpp:
+
+struct S
+{
+ S() { std::printf("not constexpr!\n"); }
+};
+
+// What is a literal type?
+
+constexpr tuple_bench<> t0{};
+static_assert(std::is_trivial<tuple_bench<>>::value, "not trivial");
+
+constexpr tuple_bench<int> t1{42};
+static_assert(std::is_trivial<tuple_bench<int>>::value, "not trivial");
+
+constexpr tuple_bench<int, float> t2{1, 3.14f};
+static_assert(std::is_trivial<tuple_bench<int, float>>::value, "not trivial");
+
+constexpr tuple_bench<int, tuple_bench<int, float>> t3{1, tuple_bench<int, float>{2, 3.14f}};
+static_assert(std::is_trivial<tuple_bench<int, tuple_bench<int, float>>>::value, "not trivial");
+
+constexpr int i = get<0>(t1);
+static_assert(i == 42, "not a compile-time constant");
+
+constexpr float f = get<1>(t2);
+static_assert(f == 3.14f, "not a compile-time constant");
+
+//static_assert(std::is_same<int, tuple_bench_element<0, tuple_bench<int>>::type>::value, "wrong element");
+//static_assert(std::is_same<float &, tuple_bench_element<1, tuple_bench<int, float &>>::type>::value, "wrong element");
+
+// Make sure I understand how decltype, rvalues and lvalues work.
+struct T { S s; };
+static_assert(!std::is_reference<decltype((T().s))>::value, "not is rvalue ref");
+static_assert(std::is_reference<decltype((static_cast<T &&>(T()).s))>::value, "is rvalue ref");
+static_assert(!std::is_lvalue_reference<decltype((static_cast<T &&>(T()).s))>::value, "is lvalue ref");
+
+void test()
+{
+ tuple_bench<S> s,t;
+ t = s;
+ S &ss = get<0>(s);
+ get<0>(s) = get<0>(t);
+ S && sss = get<0>(::make_tuple(S()));
+ static_assert(std::is_reference<decltype(get<0>(::make_tuple(S())))>::value, "");
+ static_assert(!std::is_lvalue_reference<decltype(get<0>(::make_tuple(S())))>::value, "");
+
+ int i = 0;
+ tuple_bench<int &> ti{i};
+ tuple_bench<int &> ti2(ti);
+ static_assert(std::is_lvalue_reference<decltype(get<0>(ti2))>::value, "");
+
+ static_assert(sizeof(tuple_bench<char,char,char>)==3, "wrong size");
+
+ std::printf("%f\n", (double)f);;
+}
+//}copied from unrolled_tuple.hpp:
+
+int main()
+{
+ test();
+ return 0;
+}

Modified: sandbox/variadic_templates/sandbox/slim/test/tuple_benchmark_run.py
==============================================================================
--- sandbox/variadic_templates/sandbox/slim/test/tuple_benchmark_run.py (original)
+++ sandbox/variadic_templates/sandbox/slim/test/tuple_benchmark_run.py 2012-10-26 08:54:38 EDT (Fri, 26 Oct 2012)
@@ -29,7 +29,7 @@
 
 if __name__ == '__main__':
   tuple_min_size=10
- tuple_max_size=20
+ tuple_max_size=40
   tuple_del_size=10
   boost_root="/home/evansl/prog_dev/boost-svn/ro/boost_1_49_0"
   compiler_map={}
@@ -44,14 +44,19 @@
          , "-std=c++11 -cxx-isystem /home/evansl/download/llvm/svn/llvm/projects/libcxx/include"
          )
   impl_map_hpp={}#implementation key -> implementation include .hpp file.
+ impl_map_hpp["horizontal"]="tuple_impl_horizontal.hpp"
+ impl_map_hpp["vertical" ]="tuple_impl_vertical.hpp"
+ impl_map_hpp["bcon12_horizontal"]="tuple_impl_bcon12_horizontal.hpp"
+ impl_map_hpp["bcon12_vertical" ]="tuple_impl_bcon12_vertical.hpp"
+ #impl_map_hpp["std" ]="tuple_impl_std.hpp"
+ #impl_map_hpp["compstor" ]="tuple_impl_compstor.hpp"
   impl_map_inc=collections.defaultdict(lambda:"")#implementation key -> -I include flags to compiler
- #impl_map_hpp["horizontal"]="tuple_impl_horizontal.hpp"
- #impl_map_hpp["vertical" ]="tuple_impl_vertical.hpp"
   impl_map_inc["vertical" ]=\
       " -I"+boost_root\
     #
- impl_map_hpp["std" ]="tuple_impl_std.hpp"
- impl_map_hpp["compstor" ]="tuple_impl_compstor.hpp"
+ impl_map_inc["bcon12_vertical" ]=\
+ " -I"+boost_root\
+ #
   impl_map_inc["compstor" ]=\
       " -I"+boost_root\
     + " -I"+boost_root+"/sandbox/rw/variadic_templates"\

Added: sandbox/variadic_templates/sandbox/slim/test/tuple_impl_bcon12_horizontal.hpp
==============================================================================
--- (empty file)
+++ sandbox/variadic_templates/sandbox/slim/test/tuple_impl_bcon12_horizontal.hpp 2012-10-26 08:54:38 EDT (Fri, 26 Oct 2012)
@@ -0,0 +1,204 @@
+#ifndef TUPLE_IMPL_BCON12_VERTICAL_INCLUDE_HPP
+#define TUPLE_IMPL_BCON12_VERTICAL_INCLUDE_HPP
+//Acknowlegements:
+// The following code was adapted from part of the code in
+// https://github.com/ericniebler/home/blob/master/src/tuple/tuple.cpp
+//
+///////////////////////////////////////////////////////////////////////////////
+// tuple.cpp
+//
+// Copyright 2012 Eric Niebler.
+// 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)
+//
+
+#include <cstdio>
+#include <utility>
+#include <functional>
+#include <type_traits>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/repetition/enum.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+
+#ifndef BRANCHING_FACTOR
+#define BRANCHING_FACTOR 7
+#endif
+
+#ifndef DEPTH
+#define DEPTH 7
+#endif
+
+// C++11 eliminates the need for macros! Oh, wait ...
+#define RETURN(...) -> decltype(__VA_ARGS__) { return __VA_ARGS__; }
+
+// New-style enable_if from Matt Calabrese
+#define ENABLE_IF(...) typename std::enable_if<(__VA_ARGS__)>::type *& = detail::enabler
+
+// For adding defaulted default, copy and move constructors, and move/copy assign.
+#define DEFAULTS(CLASS) \
+ CLASS() = default; /*required for the type to be trivial!*/ \
+ CLASS(CLASS const &) = default; /* memberwise copy */ \
+ CLASS(CLASS &&) = default; /* member-wise move */ \
+ /* These would otherwise be deleted because we */ \
+ /* declared a move constructor! */ \
+ CLASS &operator=(CLASS const &) = default; /* memberwise copy assign */ \
+ CLASS &operator=(CLASS &&) = default; /* memberwise move assign */ \
+ /**/
+
+namespace detail
+{
+ extern void* enabler;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // unrefwrap
+ template<typename T>
+ struct unrefwrap
+ {
+ typedef T type;
+ };
+
+ template<typename T>
+ struct unrefwrap<std::reference_wrapper<T> >
+ {
+ typedef T &type;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // as_tuple_element
+ template<typename T>
+ using as_tuple_element = typename unrefwrap<typename std::decay<T>::type>::type;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // ints
+ template<int ...I>
+ struct ints
+ {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ // indices
+ template<int N, typename Ints>
+ struct indices_;
+
+ template<int N, int... I>
+ struct indices_<N, ints<I...>>
+ : indices_<N-1, ints<N-1, I...>>
+ {};
+
+ template<int... I>
+ struct indices_<0, ints<I...>>
+ {
+ typedef ints<I...> type;
+ };
+
+ template<int I>
+ using indices = typename indices_<I, ints<>>::type;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // tuple_elem
+ template<int I, typename T>
+ struct tuple_elem
+ {
+ DEFAULTS(tuple_elem)
+
+ template<typename U
+ , ENABLE_IF(!std::is_same<U, tuple_elem &>::value)>
+ explicit constexpr tuple_elem(U &&u)
+ : value(static_cast<U &&>(u))
+ {}
+
+ typedef T type;
+ T value;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // tuple_impl
+ template<typename Ints, typename ...T>
+ struct tuple_impl;
+
+ template<int... Ints, typename H, typename ...T>
+ struct tuple_impl<ints<0, Ints...>, H, T...>
+ // can't seem to expand two packs in lock step with unrolling. Huh.
+ : tuple_elem<0, H>, tuple_elem<Ints, T>...
+ {
+ DEFAULTS(tuple_impl)
+
+ template<typename U, typename ...V
+ , ENABLE_IF(sizeof...(V) != 0 || !std::is_same<U, tuple_impl &>::value)>
+ explicit constexpr tuple_impl(U &&u, V &&...v) // HACK around gcc bug #53036
+ : tuple_elem<0, H>(static_cast<U &&>(u))
+ , tuple_elem<Ints, T>(static_cast<V &&>(v))...
+ {}
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // get
+ template<int I, typename T>
+ constexpr T &get(tuple_elem<I, T> &t) noexcept
+ {
+ return t.value;
+ }
+
+ template<int I, typename T>
+ constexpr T const &get(tuple_elem<I, T> const &t) noexcept
+ {
+ return t.value;
+ }
+
+ template<int I, typename T>
+ constexpr T &&get(tuple_elem<I, T> &&t) noexcept
+ {
+ return static_cast<T &&>(t.value);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // get_elem
+ template<int I, typename T>
+ tuple_elem<I, T> get_elem(tuple_elem<I, T> const &);
+}
+
+using detail::get;
+
+///////////////////////////////////////////////////////////////////////////////
+// tuple_element
+template<int I, typename Tuple>
+struct tuple_element
+ : decltype(detail::get_elem<I>(std::declval<Tuple>()))
+{};
+
+///////////////////////////////////////////////////////////////////////////////
+// tuple
+template<typename ...T>
+struct tuple_bench;
+
+template<>
+struct tuple_bench<>
+{};
+
+template<typename H, typename ...T>
+struct tuple_bench<H, T...>
+ : detail::tuple_impl<detail::indices<sizeof...(T) + 1>, H, T...>
+{
+ typedef detail::tuple_impl<detail::indices<sizeof...(T) + 1>, H, T...> impl_type;
+
+ DEFAULTS(tuple_bench)
+
+ // not explicit to allow things like: return {42, "allo"};
+ template<typename U, typename ...V
+ , ENABLE_IF(sizeof...(V) == sizeof...(T))
+ , ENABLE_IF(sizeof...(V) != 0 || !std::is_same<U, tuple_bench &>::value)>
+ constexpr tuple_bench(U &&u, V &&...v)
+ : impl_type(static_cast<U &&>(u), static_cast<V &&>(v)...)
+ {}
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// make_tuple
+template<typename ...T>
+tuple_bench<detail::as_tuple_element<T>...> make_tuple(T &&...t)
+{
+ return {t...};
+}
+
+#endif

Added: sandbox/variadic_templates/sandbox/slim/test/tuple_impl_bcon12_vertical.hpp
==============================================================================
--- (empty file)
+++ sandbox/variadic_templates/sandbox/slim/test/tuple_impl_bcon12_vertical.hpp 2012-10-26 08:54:38 EDT (Fri, 26 Oct 2012)
@@ -0,0 +1,196 @@
+#ifndef TUPLE_IMPL_BCON12_VERTICAL_INCLUDE_HPP
+#define TUPLE_IMPL_BCON12_VERTICAL_INCLUDE_HPP
+//Acknowlegements:
+// The following code was adapted from part of the code in
+// https://github.com/ericniebler/home/blob/master/src/tuple/unrolled_tuple.hpp
+//
+///////////////////////////////////////////////////////////////////////////////
+// unrolled_tuple.hpp
+//
+// Copyright 2012 Eric Niebler.
+// 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)
+//
+
+#include <utility>
+#include <functional>
+#include <type_traits>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/enum.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+#include <boost/preprocessor/iteration/local.hpp>
+#include <boost/preprocessor/arithmetic/dec.hpp>
+#include <boost/preprocessor/comparison/equal.hpp>
+#include <boost/preprocessor/control/expr_if.hpp>
+#include <boost/preprocessor/punctuation/comma_if.hpp>
+
+// Must be greater than or equal to 1. (1 means don't do loop unrolling.)
+#ifndef UNROLL_MAX
+#define UNROLL_MAX 10
+#endif
+
+// C++11 eliminates the need for macros! Oh, wait ...
+#define RETURN(...) -> decltype(__VA_ARGS__) { return __VA_ARGS__; }
+
+// New-style enable_if from Matt Calabrese
+#define ENABLE_IF(...) typename std::enable_if<(__VA_ARGS__)>::type *& = detail::enabler
+
+// For adding defaulted default, copy and move constructors, and move/copy assign.
+#define DEFAULTS(CLASS) \
+ CLASS() = default; /*required for the type to be trivial!*/ \
+ CLASS(CLASS const &) = default; /* memberwise copy */ \
+ CLASS(CLASS &&) = default; /* member-wise move */ \
+ /* These would otherwise be deleted because we */ \
+ /* declared a move constructor! */ \
+ CLASS &operator=(CLASS const &) = default; /* memberwise copy assign */ \
+ CLASS &operator=(CLASS &&) = default; /* memberwise move assign */ \
+ /**/
+
+#define DISABLE_COPY_IF(CLASS, N, T) \
+ BOOST_PP_COMMA_IF(BOOST_PP_EQUAL(N, 1)) \
+ BOOST_PP_EXPR_IF( \
+ BOOST_PP_EQUAL(N, 1) \
+ , ENABLE_IF(!std::is_same<T, CLASS &>::value) \
+ ) \
+ /**/
+
+namespace detail
+{
+ extern void* enabler;
+
+ ///////////////////////////////////////////////////////////////////////////
+ template<int I>
+ using int_ = std::integral_constant<int, I>;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // unrefwrap
+ template<typename T>
+ struct unrefwrap
+ {
+ typedef T type;
+ };
+
+ template<typename T>
+ struct unrefwrap<std::reference_wrapper<T> >
+ {
+ typedef T &type;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // as_tuple_element
+ template<typename T>
+ using as_tuple_element = typename unrefwrap<typename std::decay<T>::type>::type;
+}
+
+template<typename ...T>
+struct tuple_bench;
+
+template<>
+struct tuple_bench<>
+{
+};
+
+#define INIT(Z, N, D) t ## N(static_cast< U ## N && >( u ## N ))
+#define MEMBERS(Z, N, D) T ## N t ## N;
+
+#define BOOST_PP_LOCAL_MACRO(N) \
+template<BOOST_PP_ENUM_PARAMS(N, typename T)> \
+struct tuple_bench<BOOST_PP_ENUM_PARAMS(N, T)> \
+{ \
+ DEFAULTS(tuple_bench) \
+ \
+ template<BOOST_PP_ENUM_PARAMS(N, typename U) \
+ DISABLE_COPY_IF(tuple_bench, N, U0) \
+ > \
+ constexpr tuple_bench(BOOST_PP_ENUM_BINARY_PARAMS(N, U, &&u)) \
+ : BOOST_PP_ENUM(N, INIT, ~) \
+ {} \
+ \
+ BOOST_PP_REPEAT(N, MEMBERS, ~) \
+}; \
+/**/
+
+#define BOOST_PP_LOCAL_LIMITS (1, UNROLL_MAX)
+#include BOOST_PP_LOCAL_ITERATE()
+
+// A tuple type that can be statically initialized
+template<BOOST_PP_ENUM_PARAMS(UNROLL_MAX, typename T), typename ...Tail>
+struct tuple_bench<BOOST_PP_ENUM_PARAMS(UNROLL_MAX, T), Tail...>
+{
+ DEFAULTS(tuple_bench)
+
+ // Not explicit to allow things like: return {42, "allo"};.
+ template<BOOST_PP_ENUM_PARAMS(UNROLL_MAX, typename U), typename ...Rest
+ , ENABLE_IF(sizeof...(Rest)==sizeof...(Tail))
+ DISABLE_COPY_IF(tuple_bench, UNROLL_MAX, U0)
+ >
+ constexpr tuple_bench(BOOST_PP_ENUM_BINARY_PARAMS(UNROLL_MAX, U, &&u), Rest &&...rest)
+ : BOOST_PP_ENUM(UNROLL_MAX, INIT, ~)
+ , tail(static_cast<Rest &&>(rest)...) // std::forward is NOT constexpr!
+ {}
+
+ BOOST_PP_REPEAT(UNROLL_MAX, MEMBERS, ~)
+ tuple_bench<Tail...> tail;
+};
+
+#undef INIT
+#undef MEMBERS
+#undef DEFAULTS
+
+namespace detail
+{
+ // Work-around strange gcc bug
+ template<int J>
+ struct impl
+ {
+ #define BOOST_PP_LOCAL_MACRO(N) \
+ template<typename Tuple> \
+ static inline constexpr auto get_elem(Tuple &&that, int_<N>) \
+ RETURN( \
+ (static_cast<Tuple &&>(that).BOOST_PP_CAT(t, N)) /*extra parens are significant!*/ \
+ ) \
+ /**/
+
+ #define BOOST_PP_LOCAL_LIMITS (0, BOOST_PP_DEC(UNROLL_MAX))
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ template<typename Tuple, int I>
+ static inline constexpr auto get_elem(Tuple &&that, int_<I>)
+ RETURN(
+ impl<I-I>::get_elem(static_cast<Tuple &&>(that).tail, int_<I-UNROLL_MAX>())
+ )
+ };
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// get
+template<int I, typename ...T>
+inline constexpr auto get(tuple_bench<T...> &tup)
+RETURN(
+ detail::impl<I-I>::get_elem(tup, detail::int_<I>())
+)
+
+template<int I, typename ...T>
+inline constexpr auto get(tuple_bench<T...> const &tup)
+RETURN(
+ detail::impl<I-I>::get_elem(tup, detail::int_<I>())
+)
+
+template<int I, typename ...T>
+inline constexpr auto get(tuple_bench<T...> &&tup)
+RETURN(
+ detail::impl<I-I>::get_elem(static_cast<tuple_bench<T...> &&>(tup), detail::int_<I>())
+)
+
+///////////////////////////////////////////////////////////////////////////////
+// make_tuple
+template<typename ...T>
+inline tuple_bench<detail::as_tuple_element<T>...> make_tuple(T &&...t)
+{
+ return {t...};
+}
+
+#endif


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk