1762bb9d0ad20320b9f97a841dce57ba5e8e48b07Richard Smith// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s 28e8fb3be5bd78f0564444eca02b404566a5f3b5dAndy Gibbs// expected-no-diagnostics 3d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 4d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor// Example bind implementation from the variadic templates proposal, 5d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor// ISO C++ committee document number N2080. 6d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 7d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor// Helper type traits 8d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename T> 9d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorstruct add_reference { 10d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor typedef T &type; 11d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor}; 12d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 13d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename T> 14d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorstruct add_reference<T&> { 15d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor typedef T &type; 16d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor}; 17d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 18d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename T> 19d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorstruct add_const_reference { 20d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor typedef T const &type; 21d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor}; 22d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 23d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename T> 24d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorstruct add_const_reference<T&> { 25d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor typedef T &type; 26d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor}; 27d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 28d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename T, typename U> 29d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorstruct is_same { 30d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor static const bool value = false; 31d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor}; 32d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 33d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename T> 34d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorstruct is_same<T, T> { 35d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor static const bool value = true; 36d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor}; 37d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 38d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename T> 39d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorclass reference_wrapper { 40d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor T *ptr; 41d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 42d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorpublic: 43d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor reference_wrapper(T& t) : ptr(&t) { } 44d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor operator T&() const { return *ptr; } 45d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor}; 46d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 47d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename T> reference_wrapper<T> ref(T& t) { 48d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor return reference_wrapper<T>(t); 49d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor} 50d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename T> reference_wrapper<const T> cref(const T& t) { 51d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor return reference_wrapper<const T>(t); 52d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor} 53d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 54d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename... Values> class tuple; 55d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 56d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor// Basis case: zero-length tuple 57d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<> class tuple<> { }; 58d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 59d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename Head, typename... Tail> 60d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorclass tuple<Head, Tail...> : private tuple<Tail...> { 61d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor typedef tuple<Tail...> inherited; 62d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 63d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorpublic: 64d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor tuple() { } 65d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor // implicit copy-constructor is okay 66d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 67d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor // Construct tuple from separate arguments. 68d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor tuple(typename add_const_reference<Head>::type v, 69d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor typename add_const_reference<Tail>::type... vtail) 70d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor : m_head(v), inherited(vtail...) { } 71d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 72d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor // Construct tuple from another tuple. 73d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor template<typename... VValues> tuple(const tuple<VValues...>& other) 74d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor : m_head(other.head()), inherited(other.tail()) { } 75d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 76d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor template<typename... VValues> tuple& 77d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor operator=(const tuple<VValues...>& other) { 78d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor m_head = other.head(); 79d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor tail() = other.tail(); 80d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor return *this; 81d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor } 82d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 83d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor typename add_reference<Head>::type head() { return m_head; } 84d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor typename add_reference<const Head>::type head() const { return m_head; } 85d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor inherited& tail() { return *this; } 86d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor const inherited& tail() const { return *this; } 87d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 88d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorprotected: 89d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor Head m_head; 90d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor}; 91d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 92d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor// Creation functions 93d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename T> 94d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorstruct make_tuple_result { 95d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor typedef T type; 96d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor}; 97d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 98d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename T> 99d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorstruct make_tuple_result<reference_wrapper<T> > { 100d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor typedef T& type; 101d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor}; 102d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 103d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename... Values> 104d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortuple<typename make_tuple_result<Values>::type...> 105d3731198193eee92796ddeb493973b7a598b003eDouglas Gregormake_tuple(const Values&... values) { 106d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor return tuple<typename make_tuple_result<Values>::type...>(values...); 107d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor} 108d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 109d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename... Values> 110d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortuple<Values&...> tie(Values&... values) { 111d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor return tuple<Values&...>(values...); 112d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor} 113d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 114d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor// Helper classes 115d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename Tuple> struct tuple_size; 116d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 117d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename... Values> struct tuple_size<tuple<Values...> > { 118d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor static const int value = sizeof...(Values); 119d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor}; 120d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 121d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<int I, typename Tuple> struct tuple_element; 122d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 123d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<int I, typename Head, typename... Tail> 124d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorstruct tuple_element<I, tuple<Head, Tail...> > { 125d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor typedef typename tuple_element<I-1, tuple<Tail...> >::type type; 126d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor}; 127d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 128d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename Head, typename... Tail> 129d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorstruct tuple_element<0, tuple<Head, Tail...> > { 130d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor typedef Head type; 131d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor}; 132d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 133d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor// Element access 134d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<int I, typename Tuple> class get_impl; 135d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<int I, typename Head, typename... Values> 136d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorclass get_impl<I, tuple<Head, Values...> > { 137d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor typedef typename tuple_element<I-1, tuple<Values...> >::type Element; 138d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor typedef typename add_reference<Element>::type RJ; 139d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor typedef typename add_const_reference<Element>::type PJ; 140d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor typedef get_impl<I-1, tuple<Values...> > Next; 141d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorpublic: 142d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor static RJ get(tuple<Head, Values...>& t) { return Next::get(t.tail()); } 143d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor static PJ get(const tuple<Head, Values...>& t) { return Next::get(t.tail()); } 144d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor}; 145d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 146d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename Head, typename... Values> 147d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorclass get_impl<0, tuple<Head, Values...> > { 148d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor typedef typename add_reference<Head>::type RJ; 149d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor typedef typename add_const_reference<Head>::type PJ; 150d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorpublic: 151d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor static RJ get(tuple<Head, Values...>& t) { return t.head(); } 152d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor static PJ get(const tuple<Head, Values...>& t) { return t.head(); } 153d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor}; 154d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 155d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<int I, typename... Values> typename add_reference< 156d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortypename tuple_element<I, tuple<Values...> >::type >::type 157d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorget(tuple<Values...>& t) { 158d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor return get_impl<I, tuple<Values...> >::get(t); 159d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor} 160d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 161d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<int I, typename... Values> typename add_const_reference< 162d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortypename tuple_element<I, tuple<Values...> >::type >::type 163d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorget(const tuple<Values...>& t) { 164d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor return get_impl<I, tuple<Values...> >::get(t); 165d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor} 166d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 167d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor// Relational operators 168d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorinline bool operator==(const tuple<>&, const tuple<>&) { return true; } 169d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 170d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename T, typename... TTail, typename U, typename... UTail> 171d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorbool operator==(const tuple<T, TTail...>& t, const tuple<U, UTail...>& u) { 172d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor return t.head() == u.head() && t.tail() == u.tail(); 173d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor} 174d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 175d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename... TValues, typename... UValues> 176d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorbool operator!=(const tuple<TValues...>& t, const tuple<UValues...>& u) { 177d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor return !(t == u); 178d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor} 179d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 180d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorinline bool operator<(const tuple<>&, const tuple<>&) { return false; } 181d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 182d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename T, typename... TTail, typename U, typename... UTail> 183d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorbool operator<(const tuple<T, TTail...>& t, const tuple<U, UTail...>& u) { 184d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor return (t.head() < u.head() || (!(t.head() < u.head()) && t.tail() < u.tail())); 185d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor} 186d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 187d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename... TValues, typename... UValues> 188d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorbool operator>(const tuple<TValues...>& t, const tuple<UValues...>& u) { 189d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor return u < t; 190d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor} 191d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 192d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename... TValues, typename... UValues> 193d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorbool operator<=(const tuple<TValues...>& t, const tuple<UValues...>& u) { 194d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor return !(u < t); 195d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor} 196d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 197d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename... TValues, typename... UValues> 198d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorbool operator>=(const tuple<TValues...>& t, const tuple<UValues...>& u) { 199d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor return !(t < u); 200d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor} 201d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 202d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor// make_indices helper 203d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<int...> struct int_tuple {}; 204d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor// make_indexes impl is a helper for make_indexes 205d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<int I, typename IntTuple, typename... Types> struct make_indexes_impl; 206d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 207d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<int I, int... Indexes, typename T, typename... Types> 208d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorstruct make_indexes_impl<I, int_tuple<Indexes...>, T, Types...> { 209d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor typedef typename make_indexes_impl<I+1, int_tuple<Indexes..., I>, Types...>::type type; 210d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor}; 211d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 212d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<int I, int... Indexes> 213d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorstruct make_indexes_impl<I, int_tuple<Indexes...> > { 214d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor typedef int_tuple<Indexes...> type; 215d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor}; 216d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 217d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename... Types> 218d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorstruct make_indexes : make_indexes_impl<0, int_tuple<>, Types...> { 219d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor}; 220d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 221d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor// Bind 222d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename T> struct is_bind_expression { 223d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor static const bool value = false; 224d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor}; 225d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 226d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename T> struct is_placeholder { 227d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor static const int value = 0; 228d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor}; 229d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 230d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 231d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename F, typename... BoundArgs> class bound_functor { 232d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor typedef typename make_indexes<BoundArgs...>::type indexes; 233d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorpublic: 234d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor typedef typename F::result_type result_type; 235d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor explicit bound_functor(const F& f, const BoundArgs&... bound_args) 236d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor : f(f), bound_args(bound_args...) { } template<typename... Args> 237d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor typename F::result_type operator()(Args&... args); 238d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorprivate: F f; 239d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor tuple<BoundArgs...> bound_args; 240d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor}; 241d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 242d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename F, typename... BoundArgs> 243d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorinline bound_functor<F, BoundArgs...> bind(const F& f, const BoundArgs&... bound_args) { 244d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor return bound_functor<F, BoundArgs...>(f, bound_args...); 245d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor} 246d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 247d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename F, typename ...BoundArgs> 248d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorstruct is_bind_expression<bound_functor<F, BoundArgs...> > { 249d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor static const bool value = true; 250d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor}; 251d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 252d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor// enable_if helper 253d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<bool Cond, typename T = void> 254d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorstruct enable_if; 255d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 256d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename T> 257d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorstruct enable_if<true, T> { 258d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor typedef T type; 259d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor}; 260d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 261d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename T> 262d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorstruct enable_if<false, T> { }; 263d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 264d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor// safe_tuple_element helper 265d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<int I, typename Tuple, typename = void> 266d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorstruct safe_tuple_element { }; 267d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 268d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<int I, typename... Values> 269d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorstruct safe_tuple_element<I, tuple<Values...>, 270d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor typename enable_if<(I >= 0 && I < tuple_size<tuple<Values...> >::value)>::type> { 271d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor typedef typename tuple_element<I, tuple<Values...> >::type type; 272d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor}; 273d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 274d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor// mu 275d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename Bound, typename... Args> 276d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorinline typename safe_tuple_element<is_placeholder<Bound>::value -1, 277d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor tuple<Args...> >::type 278d3731198193eee92796ddeb493973b7a598b003eDouglas Gregormu(Bound& bound_arg, const tuple<Args&...>& args) { 279d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor return get<is_placeholder<Bound>::value-1>(args); 280d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor} 281d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 282d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename T, typename... Args> 283d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorinline T& mu(reference_wrapper<T>& bound_arg, const tuple<Args&...>&) { 284d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor return bound_arg.get(); 285d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor} 286d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 287d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename F, int... Indexes, typename... Args> 288d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorinline typename F::result_type 289d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorunwrap_and_forward(F& f, int_tuple<Indexes...>, const tuple<Args&...>& args) { 290d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor return f(get<Indexes>(args)...); 291d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor} 292d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 293d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename Bound, typename... Args> 294d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorinline typename enable_if<is_bind_expression<Bound>::value, 295d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor typename Bound::result_type>::type 296d3731198193eee92796ddeb493973b7a598b003eDouglas Gregormu(Bound& bound_arg, const tuple<Args&...>& args) { 297d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor typedef typename make_indexes<Args...>::type Indexes; 298d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor return unwrap_and_forward(bound_arg, Indexes(), args); 299d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor} 300d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 301d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename T> 302d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorstruct is_reference_wrapper { 303d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor static const bool value = false; 304d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor}; 305d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 306d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename T> 307d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorstruct is_reference_wrapper<reference_wrapper<T>> { 308d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor static const bool value = true; 309d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor}; 310d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 311d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename Bound, typename... Args> 312d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorinline typename enable_if<(!is_bind_expression<Bound>::value 313d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor && !is_placeholder<Bound>::value 314d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor && !is_reference_wrapper<Bound>::value), 315d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor Bound&>::type 316d3731198193eee92796ddeb493973b7a598b003eDouglas Gregormu(Bound& bound_arg, const tuple<Args&...>&) { 317d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor return bound_arg; 318d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor} 319d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 320d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename F, typename... BoundArgs, int... Indexes, typename... Args> 321d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortypename F::result_type apply_functor(F& f, tuple<BoundArgs...>& bound_args, 322d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor int_tuple<Indexes...>, 323d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor const tuple<Args&...>& args) { 324d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor return f(mu(get<Indexes>(bound_args), args)...); 325d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor} 326d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 327d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename F, typename... BoundArgs> 328d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename... Args> 329d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortypename F::result_type bound_functor<F, BoundArgs...>::operator()(Args&... args) { 330d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor return apply_functor(f, bound_args, indexes(), tie(args...)); 331d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor} 332d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 333d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<int N> struct placeholder { }; 334d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<int N> 335d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorstruct is_placeholder<placeholder<N>> { 336d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor static const int value = N; 337d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor}; 338d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 339d3731198193eee92796ddeb493973b7a598b003eDouglas Gregortemplate<typename T> 340d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorstruct plus { 341d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor typedef T result_type; 342d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 343d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor T operator()(T x, T y) { return x + y; } 344d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor}; 345d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 346d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorplaceholder<1> _1; 347d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor 348d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor// Test bind 349d3731198193eee92796ddeb493973b7a598b003eDouglas Gregorvoid test_bind() { 350d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor int x = 17; 351d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor int y = 25; 352d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor bind(plus<int>(), x, _1)(y); 353d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor} 354