diff options
author | Douglas Gregor <doug.gregor@gmail.com> | 2007-03-10 02:01:49 +0000 |
---|---|---|
committer | Doug Gregor <dgregor@gcc.gnu.org> | 2007-03-10 02:01:49 +0000 |
commit | d6a85c8dd4854845630569bbec6437170c3bc246 (patch) | |
tree | 54c92436efb921f23962b5111b0b010a5d495119 /gcc | |
parent | 5d80a306744bf10263a1f69ceda3ac8366ba6606 (diff) | |
download | gcc-d6a85c8dd4854845630569bbec6437170c3bc246.zip gcc-d6a85c8dd4854845630569bbec6437170c3bc246.tar.gz gcc-d6a85c8dd4854845630569bbec6437170c3bc246.tar.bz2 |
re PR c++/20599 (variadic template support)
2007-03-09 Douglas Gregor <doug.gregor@gmail.com>
PR c++/20599
* g++.dg/cpp0x/variadic-bind.C: New.
* g++.dg/cpp0x/variadic-function.C: New.
* g++.dg/cpp0x/variadic-mem_fn.C: New.
* g++.dg/cpp0x/variadic-tuple.C: New.
* g++.dg/cpp0x/variadic1.C: New.
* g++.dg/cpp0x/variadic2.C: New.
* g++.dg/cpp0x/variadic3.C: New.
* g++.dg/cpp0x/variadic4.C: New.
* g++.dg/cpp0x/variadic5.C: New.
* g++.dg/cpp0x/variadic6.C: New.
* g++.dg/cpp0x/variadic7.C: New.
* g++.dg/cpp0x/variadic8.C: New.
* g++.dg/cpp0x/variadic9.C: New.
* g++.dg/cpp0x/variadic10.C: New.
* g++.dg/cpp0x/variadic11.C: New.
* g++.dg/cpp0x/variadic12.C: New.
* g++.dg/cpp0x/variadic13.C: New.
* g++.dg/cpp0x/variadic14.C: New.
* g++.dg/cpp0x/variadic15.C: New.
* g++.dg/cpp0x/variadic16.C: New.
* g++.dg/cpp0x/variadic17.C: New.
* g++.dg/cpp0x/variadic18.C: New.
* g++.dg/cpp0x/variadic19.C: New.
* g++.dg/cpp0x/variadic20.C: New.
* g++.dg/cpp0x/variadic21.C: New.
* g++.dg/cpp0x/variadic22.C: New.
* g++.dg/cpp0x/variadic23.C: New.
* g++.dg/cpp0x/variadic24.C: New.
* g++.dg/cpp0x/variadic25.C: New.
* g++.dg/cpp0x/variadic26.C: New.
* g++.dg/cpp0x/variadic27.C: New.
* g++.dg/cpp0x/variadic28.C: New.
* g++.dg/cpp0x/variadic29.C: New.
* g++.dg/cpp0x/variadic30.C: New.
* g++.dg/cpp0x/variadic31.C: New.
* g++.dg/cpp0x/variadic32.C: New.
* g++.dg/cpp0x/variadic33.C: New.
* g++.dg/cpp0x/variadic34.C: New.
* g++.dg/cpp0x/variadic35.C: New.
* g++.dg/cpp0x/variadic36.C: New.
* g++.dg/cpp0x/variadic37.C: New.
* g++.dg/cpp0x/variadic38.C: New.
* g++.dg/cpp0x/variadic39.C: New.
* g++.dg/cpp0x/variadic40.C: New.
* g++.dg/cpp0x/variadic41.C: New.
* g++.dg/cpp0x/variadic42.C: New.
* g++.dg/cpp0x/variadic43.C: New.
* g++.dg/cpp0x/variadic44.C: New.
* g++.dg/cpp0x/variadic45.C: New.
* g++.dg/cpp0x/variadic46.C: New.
* g++.dg/cpp0x/variadic47.C: New.
* g++.dg/cpp0x/variadic48.C: New.
* g++.dg/cpp0x/variadic49.C: New.
* g++.dg/cpp0x/variadic50.C: New.
* g++.dg/cpp0x/variadic51.C: New.
* g++.dg/cpp0x/variadic52.C: New.
* g++.dg/cpp0x/variadic53.C: New.
* g++.dg/cpp0x/variadic54.C: New.
* g++.dg/cpp0x/variadic55.C: New.
* g++.dg/cpp0x/variadic56.C: New.
* g++.dg/cpp0x/variadic57.C: New.
* g++.dg/cpp0x/variadic58.C: New.
* g++.dg/cpp0x/variadic59.C: New.
* g++.dg/cpp0x/variadic60.C : New.
* g++.dg/cpp0x/variadic61.C : New.
* g++.dg/cpp0x/variadic62.C : New.
* g++.dg/cpp0x/variadic63.C : New.
* g++.dg/cpp0x/variadic64.C : New.
* g++.dg/cpp0x/variadic65.C : New.
* g++.dg/cpp0x/variadic66.C : New.
* g++.dg/cpp0x/variadic67.C : New.
* g++.dg/cpp0x/variadic68.C : New.
* g++.dg/cpp0x/variadic69.C : New.
* g++.dg/cpp0x/variadic70.C : New.
* g++.dg/cpp0x/variadic71.C : New.
* g++.dg/cpp0x/variadic72.C : New.
* g++.dg/cpp0x/variadic73.C : New.
* g++.dg/cpp0x/variadic74.C : New.
* g++.dg/cpp0x/variadic75.C : New.
* g++.dg/cpp0x/variadic-ex1.C : New.
* g++.dg/cpp0x/variadic-ex2.C : New.
* g++.dg/cpp0x/variadic-ex3.C : New.
* g++.dg/cpp0x/variadic-ex4.C : New.
* g++.dg/cpp0x/variadic-ex5.C : New.
* g++.dg/cpp0x/variadic-ex6.C : New.
* g++.dg/cpp0x/variadic-ex7.C : New.
* g++.dg/cpp0x/variadic-ex8.C : New.
* g++.dg/cpp0x/variadic-ex9.C : New.
* g++.dg/cpp0x/variadic-ex10.C : New.
* g++.dg/cpp0x/variadic-ex11.C : New.
* g++.dg/cpp0x/variadic-ex12.C : New.
* g++.dg/cpp0x/variadic-ex13.C : New.
* g++.dg/cpp0x/variadic-ex14.C : New.
From-SVN: r122789
Diffstat (limited to 'gcc')
94 files changed, 2473 insertions, 0 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f9c1c3f..d71b94f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,100 @@ +2007-03-09 Douglas Gregor <doug.gregor@gmail.com> + + PR c++/20599 + * g++.dg/cpp0x/variadic-bind.C: New. + * g++.dg/cpp0x/variadic-function.C: New. + * g++.dg/cpp0x/variadic-mem_fn.C: New. + * g++.dg/cpp0x/variadic-tuple.C: New. + * g++.dg/cpp0x/variadic1.C: New. + * g++.dg/cpp0x/variadic2.C: New. + * g++.dg/cpp0x/variadic3.C: New. + * g++.dg/cpp0x/variadic4.C: New. + * g++.dg/cpp0x/variadic5.C: New. + * g++.dg/cpp0x/variadic6.C: New. + * g++.dg/cpp0x/variadic7.C: New. + * g++.dg/cpp0x/variadic8.C: New. + * g++.dg/cpp0x/variadic9.C: New. + * g++.dg/cpp0x/variadic10.C: New. + * g++.dg/cpp0x/variadic11.C: New. + * g++.dg/cpp0x/variadic12.C: New. + * g++.dg/cpp0x/variadic13.C: New. + * g++.dg/cpp0x/variadic14.C: New. + * g++.dg/cpp0x/variadic15.C: New. + * g++.dg/cpp0x/variadic16.C: New. + * g++.dg/cpp0x/variadic17.C: New. + * g++.dg/cpp0x/variadic18.C: New. + * g++.dg/cpp0x/variadic19.C: New. + * g++.dg/cpp0x/variadic20.C: New. + * g++.dg/cpp0x/variadic21.C: New. + * g++.dg/cpp0x/variadic22.C: New. + * g++.dg/cpp0x/variadic23.C: New. + * g++.dg/cpp0x/variadic24.C: New. + * g++.dg/cpp0x/variadic25.C: New. + * g++.dg/cpp0x/variadic26.C: New. + * g++.dg/cpp0x/variadic27.C: New. + * g++.dg/cpp0x/variadic28.C: New. + * g++.dg/cpp0x/variadic29.C: New. + * g++.dg/cpp0x/variadic30.C: New. + * g++.dg/cpp0x/variadic31.C: New. + * g++.dg/cpp0x/variadic32.C: New. + * g++.dg/cpp0x/variadic33.C: New. + * g++.dg/cpp0x/variadic34.C: New. + * g++.dg/cpp0x/variadic35.C: New. + * g++.dg/cpp0x/variadic36.C: New. + * g++.dg/cpp0x/variadic37.C: New. + * g++.dg/cpp0x/variadic38.C: New. + * g++.dg/cpp0x/variadic39.C: New. + * g++.dg/cpp0x/variadic40.C: New. + * g++.dg/cpp0x/variadic41.C: New. + * g++.dg/cpp0x/variadic42.C: New. + * g++.dg/cpp0x/variadic43.C: New. + * g++.dg/cpp0x/variadic44.C: New. + * g++.dg/cpp0x/variadic45.C: New. + * g++.dg/cpp0x/variadic46.C: New. + * g++.dg/cpp0x/variadic47.C: New. + * g++.dg/cpp0x/variadic48.C: New. + * g++.dg/cpp0x/variadic49.C: New. + * g++.dg/cpp0x/variadic50.C: New. + * g++.dg/cpp0x/variadic51.C: New. + * g++.dg/cpp0x/variadic52.C: New. + * g++.dg/cpp0x/variadic53.C: New. + * g++.dg/cpp0x/variadic54.C: New. + * g++.dg/cpp0x/variadic55.C: New. + * g++.dg/cpp0x/variadic56.C: New. + * g++.dg/cpp0x/variadic57.C: New. + * g++.dg/cpp0x/variadic58.C: New. + * g++.dg/cpp0x/variadic59.C: New. + * g++.dg/cpp0x/variadic60.C : New. + * g++.dg/cpp0x/variadic61.C : New. + * g++.dg/cpp0x/variadic62.C : New. + * g++.dg/cpp0x/variadic63.C : New. + * g++.dg/cpp0x/variadic64.C : New. + * g++.dg/cpp0x/variadic65.C : New. + * g++.dg/cpp0x/variadic66.C : New. + * g++.dg/cpp0x/variadic67.C : New. + * g++.dg/cpp0x/variadic68.C : New. + * g++.dg/cpp0x/variadic69.C : New. + * g++.dg/cpp0x/variadic70.C : New. + * g++.dg/cpp0x/variadic71.C : New. + * g++.dg/cpp0x/variadic72.C : New. + * g++.dg/cpp0x/variadic73.C : New. + * g++.dg/cpp0x/variadic74.C : New. + * g++.dg/cpp0x/variadic75.C : New. + * g++.dg/cpp0x/variadic-ex1.C : New. + * g++.dg/cpp0x/variadic-ex2.C : New. + * g++.dg/cpp0x/variadic-ex3.C : New. + * g++.dg/cpp0x/variadic-ex4.C : New. + * g++.dg/cpp0x/variadic-ex5.C : New. + * g++.dg/cpp0x/variadic-ex6.C : New. + * g++.dg/cpp0x/variadic-ex7.C : New. + * g++.dg/cpp0x/variadic-ex8.C : New. + * g++.dg/cpp0x/variadic-ex9.C : New. + * g++.dg/cpp0x/variadic-ex10.C : New. + * g++.dg/cpp0x/variadic-ex11.C : New. + * g++.dg/cpp0x/variadic-ex12.C : New. + * g++.dg/cpp0x/variadic-ex13.C : New. + * g++.dg/cpp0x/variadic-ex14.C : New. + 2007-03-09 Jerry DeLisle <jvdelisle@gcc.gnu.org> PR libgfortran/31099 diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-bind.C b/gcc/testsuite/g++.dg/cpp0x/variadic-bind.C new file mode 100644 index 0000000..b9f9f67 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-bind.C @@ -0,0 +1,476 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do "run" } +// A basic implementation of TR1's bind using variadic teplates +// Contributed by Douglas Gregor <doug.gregor@gmail.com> +#include <cassert> + +// Trivial reference_wrapper +template<typename T> +struct reference_wrapper +{ + reference_wrapper(T& x) : ptr(&x) { } + + operator T&() const { return *ptr; } + + T& get() const { return *ptr; } + + T* ptr; +}; + +template<typename T> reference_wrapper<T> ref(T& x) { return x; } +template<typename T> reference_wrapper<const T> cref(const T& x) { return x; } + +// Simple type-traits we'll need +template<typename T> +struct add_reference +{ + typedef T& type; +}; + +template<typename T> +struct add_reference<T&> +{ + typedef T& type; +}; + +template<typename T, typename U> +struct is_same +{ + static const bool value = false; +}; + +template<typename T> +struct is_same<T, T> +{ + static const bool value = true; +}; + +// For creating the constructor parameters of tuple<> +template<typename T> +struct add_const_reference +{ + typedef const T& type; +}; + +template<typename T> +struct add_const_reference<T&> +{ + typedef T& type; +}; + +// 6.1.3 Class template tuple: Needed for bind() implementation +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 + + tuple(typename add_const_reference<Head>::type v, + typename add_const_reference<Tail>::type... vtail) + : m_head(v), inherited(vtail...) { } + + 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 T> +struct make_tuple_result +{ + typedef T type; +}; + +template<typename T> +struct make_tuple_result<reference_wrapper<T> > +{ + typedef T& type; +}; + +// 6.1.3.2 Tuple creation functions +struct ignore_t { + template<typename T> ignore_t& operator=(const T&) { return *this; } +} ignore; + +template<typename... Values> +tuple<typename make_tuple_result<Values>::type...> +make_tuple(const Values&... values) +{ + return tuple<typename make_tuple_result<Values>::type...>(values...); +} + +template<typename... Values> +tuple<Values&...> tie(Values&... values) +{ + return tuple<Values&...>(values...); +} + +// 6.1.3.3 Tuple helper classes +template<typename Tuple> +struct tuple_size; + +template<> +struct tuple_size<tuple<> > +{ + static const __SIZE_TYPE__ value = 0; +}; + +template<typename Head, typename... Tail> +struct tuple_size<tuple<Head, Tail...> > +{ + static const __SIZE_TYPE__ value = 1 + tuple_size<tuple<Tail...> >::value; +}; + +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; +}; + +// 6.1.3.4 Element access +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 typename add_reference<Element>::type RJ; + typedef typename add_const_reference<Element>::type PJ; + typedef get_impl<I-1, tuple<Values...> > Next; + + public: + static RJ get(tuple<Head, Values...>& t) + { return Next::get(t.tail()); } + + static PJ get(const tuple<Head, Values...>& t) + { return Next::get(t.tail()); } +}; + +template<typename Head, typename... Values> +class get_impl<0, tuple<Head, Values...> > +{ + typedef typename add_reference<Head>::type RJ; + typedef typename add_const_reference<Head>::type PJ; + + public: + static RJ get(tuple<Head, Values...>& t) { return t.head(); } + static PJ get(const tuple<Head, Values...>& t) { return t.head(); } +}; + +template<int I, typename... Values> +typename add_reference< + typename tuple_element<I, tuple<Values...> >::type + >::type +get(tuple<Values...>& t) +{ + return get_impl<I, tuple<Values...> >::get(t); +} + +template<int I, typename... Values> +typename add_const_reference< + typename tuple_element<I, tuple<Values...> >::type + >::type +get(const tuple<Values...>& t) +{ + return get_impl<I, tuple<Values...> >::get(t); +} + +// 6.1.3.5 Relational operators +inline bool operator==(const tuple<>&, const tuple<>&) { return true; } + +template<typename T, typename... TTail, typename U, typename... UTail> +bool operator==(const tuple<T, TTail...>& t, const tuple<U, UTail...>& u) +{ + return t.head() == u.head() && t.tail() == u.tail(); +} + +template<typename... TValues, typename... UValues> +bool operator!=(const tuple<TValues...>& t, const tuple<UValues...>& u) +{ + return !(t == u); +} + +inline bool operator<(const tuple<>&, const tuple<>&) { return false; } + +template<typename T, typename... TTail, typename U, typename... UTail> +bool operator<(const tuple<T, TTail...>& t, const tuple<U, UTail...>& u) +{ + return (t.head() < u.head() || + (!(t.head() < u.head()) && t.tail() < u.tail())); +} + +template<typename... TValues, typename... UValues> +bool operator>(const tuple<TValues...>& t, const tuple<UValues...>& u) +{ + return u < t; +} + +template<typename... TValues, typename... UValues> +bool operator<=(const tuple<TValues...>& t, const tuple<UValues...>& u) +{ + return !(u < t); +} + +template<typename... TValues, typename... UValues> +bool operator>=(const tuple<TValues...>& t, const tuple<UValues...>& u) +{ + return !(t < u); +} + +// enable_if, the breakfast of champions +template<bool Cond, typename Type = void> +struct enable_if { + typedef Type type; +}; + +template<typename Type> +struct enable_if<false, Type> { }; + +// 3.6 Function object binders + +// 3.6.1 Class template is_bind_expression +template<typename T> +struct is_bind_expression { + static const bool value = false; +}; + +// 3.6.2 Class template is_placeholder +template<typename T> +struct is_placeholder { + static const int value = 0; +}; + +// 3.6.3 Function template bind +template<int I> struct placeholder {} ; + +template<int N> struct int_c { }; + +// A tuple of integer values +template<int...> struct int_tuple {}; + +// make_indexes_impl is a helper for make_indexes +template<int I, typename IntTuple, typename... Types> +struct make_indexes_impl; + + +template<int I, int... Indexes, typename T, typename... Types> +struct make_indexes_impl<I, int_tuple<Indexes...>, T, Types...> +{ + typedef typename make_indexes_impl<I+1, + int_tuple<Indexes..., I>, + Types...>::type type; +}; + +template<int I, int... Indexes> +struct make_indexes_impl<I, int_tuple<Indexes...> > { + typedef int_tuple<Indexes...> type; +}; + +// make_indexes takes a variable-length number of N types and +// generates an int_tuple that contains <0, 1, 2, ..., N-1>. These can +// be used as indexes for tuple's get or tuple_element operation. +template<typename... Types> +struct make_indexes : make_indexes_impl<0, int_tuple<>, Types...> { }; + +// Get the Ith tuple element, but only if I is in bounds. +template<int I, typename Tuple, typename = void> +struct safe_tuple_element{ }; + +template<int I, typename... Values> +struct safe_tuple_element<I, tuple<Values...>, + typename enable_if<(I >= 0 && + I < tuple_size<tuple<Values...> >::value) + >::type> +{ + typedef typename tuple_element<I, tuple<Values...> >::type type; +}; + +// mu maps a bound argument to an actual argument, given a tuple of +// the arguments passed to the function object returned by bind(). + +// Return the stored reference from reference_wrapper +template<typename T, typename... Args> +inline T& mu(reference_wrapper<T>& bound_arg, const tuple<Args&...>&) +{ + return bound_arg.get(); +} + +// Unwrap a tuple into separate arguments and forward to the function +// object f. +template<typename F, int... Indexes, typename... Args> +inline typename F::result_type +unwrap_and_forward(F& f, int_tuple<Indexes...>, const tuple<Args&...>& args) +{ + return f(get<Indexes>(args)...); +} + +// Evaluate the inner bind expression +template<typename Bound, typename... Args> +inline typename enable_if<is_bind_expression<Bound>::value, + typename Bound::result_type>::type +mu(Bound& bound_arg, const tuple<Args&...>& args) +{ + typedef typename make_indexes<Args...>::type Indexes; + return unwrap_and_forward(bound_arg, Indexes(), args); +} + +// Retrieve the Ith argument from args +template<typename Bound, typename... Args> +inline typename safe_tuple_element<is_placeholder<Bound>::value - 1, + tuple<Args...> >::type +mu(Bound& bound_arg, const tuple<Args&...>& args) +{ + return get<is_placeholder<Bound>::value-1>(args); +} + +// Return the stored value. +template<typename T> +struct is_reference_wrapper { + static const bool value = false; +}; + +template<typename T> +struct is_reference_wrapper<reference_wrapper<T> > { + static const bool value = true; +}; + +template<typename Bound, typename... Args> +inline typename enable_if<(!is_bind_expression<Bound>::value + && !is_placeholder<Bound>::value + && !is_reference_wrapper<Bound>::value), + Bound&>::type +mu(Bound& bound_arg, const tuple<Args&...>&) +{ + return bound_arg; +} + +// +template<typename F, typename... BoundArgs, int... Indexes, typename... Args> +typename F::result_type +apply_functor(F& f, tuple<BoundArgs...>& bound_args, int_tuple<Indexes...>, + const tuple<Args&...>& args) +{ + return f(mu(get<Indexes>(bound_args), args)...); +} + +template<typename F, typename... BoundArgs> +class bound_functor +{ + typedef typename make_indexes<BoundArgs...>::type indexes; + + public: + typedef typename F::result_type result_type; + + explicit bound_functor(const F& f, const BoundArgs&... bound_args) + : f(f), bound_args(bound_args...) { } + + template<typename... Args> + typename F::result_type operator()(Args&... args) { + return apply_functor(f, bound_args, indexes(), tie(args...)); + } + + private: + F f; + tuple<BoundArgs...> bound_args; +}; + +template<typename F, typename... BoundArgs> +struct is_bind_expression<bound_functor<F, BoundArgs...> > { + static const bool value = true; +}; + +template<typename F, typename... BoundArgs> +inline bound_functor<F, BoundArgs...> +bind(const F& f, const BoundArgs&... bound_args) +{ + return bound_functor<F, BoundArgs...>(f, bound_args...); +} + + +// 3.6.4 Placeholders +template<int I> +struct is_placeholder<placeholder<I> > { + static const int value = I; +}; + +placeholder<1> _1; +placeholder<2> _2; +placeholder<3> _3; +placeholder<4> _4; +placeholder<5> _5; +placeholder<6> _6; +placeholder<7> _7; +placeholder<8> _8; +placeholder<9> _9; + +// Test code +template<typename T> +struct plus { + typedef T result_type; + + T operator()(T x, T y) { return x + y; } +}; + +template<typename T> +struct multiplies { + typedef T result_type; + + T operator()(T x, T y) { return x * y; } +}; + +template<typename T> +struct negate { + typedef T result_type; + + T operator()(T x) { return -x; } +}; + +int main() +{ + int seventeen = 17; + int forty_two = 42; + + assert(bind(plus<int>(), _1, _2)(seventeen, forty_two) == 59); + assert(bind(plus<int>(), _1, _1)(seventeen, forty_two) == 34); + assert(bind(plus<int>(), _2, _1)(seventeen, forty_two) == 59); + assert(bind(plus<int>(), 5, _1)(seventeen, forty_two) == 22); + assert(bind(plus<int>(), ref(seventeen), _2)(seventeen, forty_two) == 59); + assert(bind(plus<int>(), bind(multiplies<int>(), 3, _1), _2)(seventeen, forty_two) + == 93); + return 0; +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-ex1.C b/gcc/testsuite/g++.dg/cpp0x/variadic-ex1.C new file mode 100644 index 0000000..d5ebf0d --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-ex1.C @@ -0,0 +1,4 @@ +// { dg-options "-std=gnu++0x" } +template<typename ... Elements> class Tuple; +Tuple<>* t; // OK: Elements is empty +Tuple* u; // { dg-error "expected" } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-ex10.C b/gcc/testsuite/g++.dg/cpp0x/variadic-ex10.C new file mode 100644 index 0000000..a392bd7 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-ex10.C @@ -0,0 +1,9 @@ +// { dg-options "-std=gnu++0x" } +template<typename... Types> struct Tuple { }; + +Tuple<> t0; // Types contains no arguments +Tuple<int> t1; // Types contains one argument: int +Tuple<int, float> t2; // Types contains two arguments: int and float +Tuple<0> error; // { dg-error "mismatch" } +// { dg-error "expected a type" "" { target *-*-* } 7 } +// { dg-error "in declaration" "" { target *-*-* } 7 } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-ex11.C b/gcc/testsuite/g++.dg/cpp0x/variadic-ex11.C new file mode 100644 index 0000000..57ef2a3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-ex11.C @@ -0,0 +1,9 @@ +// { dg-options "-std=gnu++0x" } +template<typename... Types> + void f(Types... args); + +void g() { + f(); // okay: args contains no arguments + f(1); // okay: args contains one int argument + (2, 1.0); // okay: args contains two arguments, an int and a double +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-ex12.C b/gcc/testsuite/g++.dg/cpp0x/variadic-ex12.C new file mode 100644 index 0000000..b97df31 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-ex12.C @@ -0,0 +1,8 @@ +// { dg-options "-std=gnu++0x" } +template<typename... Types> + void f(Types... rest); + +template<typename... Types> + void g(Types... rest) { + f(&rest...); // ``&rest...'' is a pack expansion, ``&rest'' is its pattern + } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-ex13.C b/gcc/testsuite/g++.dg/cpp0x/variadic-ex13.C new file mode 100644 index 0000000..f1cce3a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-ex13.C @@ -0,0 +1,39 @@ +// { dg-options "-std=gnu++0x" } + +template<typename T, typename U> struct is_same { + static const bool value = false; +}; + +template<typename T> struct is_same<T, T> { + static const bool value = true; +}; + +template<typename...> struct Tuple {}; +template<typename T1, typename T2> struct Pair {}; + +template<typename... Args1> + struct zip { + template<typename... Args2> + struct with { + typedef Tuple<Pair<Args1, Args2>...> type; // { dg-error "mismatched argument pack" } + }; + }; + +static_assert + (is_same<zip<short, int>::with<unsigned short, unsigned>::type, + Tuple<Pair<short, unsigned short>, Pair<int, unsigned> > >::value, + "zip"); + +typedef zip<short>::with<unsigned short, unsigned>::type T2; // error: different number of arguments specified + // for Args1 and Args2 + +template<typename... Args> void f(Args...); + +template<typename... Args> void g(Args... args) +{ + f(const_cast<const Args*>(&args)...); // okay: ``Args'' and ``args'' are expanded + f(5 ...); // { dg-error "contains no argument packs" } + f(args); // { dg-error "parameter packs not expanded" } + // { dg-error "args" "" { target *-*-* } 36 } + f(h(args...) + args...); // okay: first ``args'' expanded within h, second ``args'' expanded within f. +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-ex14.C b/gcc/testsuite/g++.dg/cpp0x/variadic-ex14.C new file mode 100644 index 0000000..7050256 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-ex14.C @@ -0,0 +1,23 @@ +// { dg-options "-std=gnu++0x" } + +template<class T> class A { /* ... */ }; +template<class T, class U = T> class B { /* ... */ }; +template<class... Types> class C { /* ... */ }; + +template<template<class> class P> class X { /* ... */ }; +template<template<class...> class Q> class Y { /* ... */ }; + +X<A> xA; // okay +X<B> xB; // { dg-error "mismatch" } +// { dg-error "expected a template" "" { target *-*-* } 11 } +// { dg-error "invalid type" "" { target *-*-* } 11 } +X<C> xC; // { dg-error "mismatch" } +// { dg-error "expected a template" "" { target *-*-* } 14 } +// { dg-error "invalid type" "" { target *-*-* } 14 } +Y<A> yA; // { dg-error "mismatch" } +// { dg-error "expected a template" "" { target *-*-* } 17 } +// { dg-error "invalid type" "" { target *-*-* } 17 } +Y<B> yB; // { dg-error "mismatch" } +// { dg-error "expected a template" "" { target *-*-* } 20 } +// { dg-error "invalid type" "" { target *-*-* } 20 } +Y<C> yC; // okay diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-ex2.C b/gcc/testsuite/g++.dg/cpp0x/variadic-ex2.C new file mode 100644 index 0000000..ca5fa27 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-ex2.C @@ -0,0 +1,8 @@ +// { dg-options "-std=gnu++0x" } +template<class... Types> struct B { // { dg-error "declaration of" } + void f3(); + void f4(); +}; + +template<class... Types> void B<Types...>::f3() { } // OK +template<class... Types> void B<Types>::f4() { } // { dg-error "invalid" } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-ex3.C b/gcc/testsuite/g++.dg/cpp0x/variadic-ex3.C new file mode 100644 index 0000000..8b8ca9e --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-ex3.C @@ -0,0 +1,9 @@ +// { dg-options "-std=gnu++0x" } +template<class X, class Y, class... Z> X f(Y); +void g() +{ + int i = f<int>(5.6); + int j = f(5.6); // { dg-error "no matching" } + f<void>(f<int, bool>); + f<void>(f<int>); // { dg-error "no matching" } +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-ex4.C b/gcc/testsuite/g++.dg/cpp0x/variadic-ex4.C new file mode 100644 index 0000000..69866dc --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-ex4.C @@ -0,0 +1,12 @@ +// { dg-options "-std=gnu++0x" } +template<class X, class Y, class Z> X f(Y,Z); +template<class... Args> void f2(); +void g() +{ + f<int,const char*,double>("aa",3.0); + f<int,const char*>("aa",3.0); // Z is deduced to be double + f<int>("aa",3.0); // Y is deduced to be char*, and + // Z is deduced to be double + f("aa",3.0); // { dg-error "no matching" } + f2<char, short, int, long>(); // okay +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-ex5.C b/gcc/testsuite/g++.dg/cpp0x/variadic-ex5.C new file mode 100644 index 0000000..2439a51 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-ex5.C @@ -0,0 +1,7 @@ +// { dg-options "-std=gnu++0x" } +template<typename... Types> void f(Types... values); + +void g() +{ + f<int*, float*>(0, 0, 0); // Types is deduced to the sequence int*, float*, int +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-ex6.C b/gcc/testsuite/g++.dg/cpp0x/variadic-ex6.C new file mode 100644 index 0000000..87b1bf2 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-ex6.C @@ -0,0 +1,13 @@ +// { dg-options "-std=gnu++0x" } +template<class...> struct Tuple { }; + +template<class... Types> void f(Types&...); +template<class... Types1, class... Types2> void g(Tuple<Types1...>, Tuple<Types2...>); + +void h(int x, float& y) +{ + const int z = x; + f(x, y, z); // Types is deduced to int, const int, float + g(Tuple<short, int, long>(), Tuple<float, double>()); // Types1 is deduced to short, int long + // Types2 is deduced to float, double +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-ex7.C b/gcc/testsuite/g++.dg/cpp0x/variadic-ex7.C new file mode 100644 index 0000000..7ca31f9 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-ex7.C @@ -0,0 +1,13 @@ +// { dg-options "-std=gnu++0x" } +template<typename...> struct Tuple { }; +template<typename... Types> char& g(Tuple<Types...>); // #1 +template<typename T1, typename... Types> short& g(Tuple<T1, Types...>); // #2 +template<typename T1, typename... Types> int& g(Tuple<T1, Types&...>); // #3 + +void f() { + // char& x1 = g(Tuple<>()); // calls #1 + short& y1 = g(Tuple<int, float>()); // calls #2 + // int& z1 = g(Tuple<int, float&>()); // calls #3 + // int& z2 = g(Tuple<int>()); // calls #3 + // int& z3 = g(Tuple<int>()); // calls #3 +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-ex8.C b/gcc/testsuite/g++.dg/cpp0x/variadic-ex8.C new file mode 100644 index 0000000..03d28b8 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-ex8.C @@ -0,0 +1,18 @@ +// { dg-options "-std=gnu++0x" } +template<class> struct X { static const bool primary = true; }; +template<class R, class... ArgTypes> struct X<R(int, ArgTypes...)> { + static const bool primary = false; +}; +template<class... Types> struct Y { static const bool primary = true; }; +template<class T, class... Types> struct Y<T, Types&...> { + static const bool primary = false; +}; + +static_assert (X<int>::primary, "uses primary template"); +static_assert (!X<int(int, float, double)>::primary, + "uses partial specialization"); +static_assert (X<int(float, int)>::primary, "uses primary template"); +static_assert (Y<>::primary, "uses primary template"); +static_assert (!Y<int&, float&, double&>::primary, + "uses partial specialization"); +static_assert (Y<int, float, double>::primary, "uses primary template"); diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-ex9.C b/gcc/testsuite/g++.dg/cpp0x/variadic-ex9.C new file mode 100644 index 0000000..ec78a7a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-ex9.C @@ -0,0 +1,10 @@ +// { dg-options "-std=gnu++0x" } +template<typename... Args> char& f(Args... args); // #1 +template<typename T1, typename... Args> short& f(T1 a1, Args... args); // #2 +template<typename T1, typename T2> int& f(T1 a2, T2 a2); // #3 + +void g() { + char& x = f(); // calls #1 + short& y = f(1, 2, 3); // calls #2 + int& z = f(1, 2); // calls #3 +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-function.C b/gcc/testsuite/g++.dg/cpp0x/variadic-function.C new file mode 100644 index 0000000..0373efd --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-function.C @@ -0,0 +1,96 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do "run" } +// A basic implementation of TR1's function using variadic teplates +// Contributed by Douglas Gregor <doug.gregor@gmail.com> +#include <cassert> + +template<typename Signature> +class function; + +template<typename R, typename... Args> +class invoker_base +{ + public: + virtual ~invoker_base() { } + virtual R invoke(Args...) = 0; + virtual invoker_base* clone() = 0; +}; + +template<typename F, typename R, typename... Args> +class functor_invoker : public invoker_base<R, Args...> +{ + public: + explicit functor_invoker(const F& f) : f(f) { } + R invoke(Args... args) { return f(args...); } + functor_invoker* clone() { return new functor_invoker(f); } + + private: + F f; +}; + +template<typename R, typename... Args> +class function<R (Args...)> { + public: + typedef R result_type; + + function() : invoker (0) { } + + function(const function& other) : invoker(0) { + if (other.invoker) + invoker = other.invoker->clone(); + } + + template<typename F> + function(const F& f) : invoker(0) { + invoker = new functor_invoker<F, R, Args...>(f); + } + + ~function() { + if (invoker) + delete invoker; + } + + function& operator=(const function& other) { + function(other).swap(*this); + return *this; + } + + template<typename F> + function& operator=(const F& f) { + function(f).swap(*this); + return *this; + } + + void swap(function& other) { + invoker_base<R, Args...>* tmp = invoker; + invoker = other.invoker; + other.invoker = tmp; + } + + result_type operator()(Args... args) const { + assert(invoker); + return invoker->invoke(args...); + } + + private: + invoker_base<R, Args...>* invoker; +}; + +struct plus { + template<typename T> T operator()(T x, T y) { return x + y; } +}; + +struct multiplies { + template<typename T> T operator()(T x, T y) { return x * y; } +}; + +int main() +{ + function<int(int, int)> f1 = plus(); + assert(f1(3, 5) == 8); + + f1 = multiplies(); + assert(f1(3, 5) == 15); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-mem_fn.C b/gcc/testsuite/g++.dg/cpp0x/variadic-mem_fn.C new file mode 100644 index 0000000..6e29d3b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-mem_fn.C @@ -0,0 +1,50 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do "run" } +// A basic implementation of TR1's mem_fn using variadic teplates +// Contributed by Douglas Gregor <doug.gregor@gmail.com> +#include <cassert> + +template<typename R, typename Class, typename... Args> +class Mem_fn +{ + public: + explicit Mem_fn(R (Class::*pmf)(Args...)) : pmf(pmf) { } + + R operator()(Class& object, Args... args) + { + return (object.*pmf)(args...); + } + + R operator()(Class* object, Args... args) + { + return (object->*pmf)(args...); + } + + R (Class::*pmf)(Args...); +}; + +template<typename R, typename Class, typename... Args> +inline Mem_fn<R, Class, Args...> +mem_fn(R (Class::* pmf)(Args...)) +{ + return Mem_fn<R, Class, Args...>(pmf); +} + +class X { + public: + int negate(int x) { return -x; } + int plus(int x, int y) { return x + y; } +}; + +int main() +{ + X x; + X* xp = &x; + + assert(mem_fn(&X::negate)(x, 17) == -17); + assert(mem_fn(&X::negate)(xp, 17) == -17); + assert(mem_fn(&X::plus)(x, 17, 25) == 42); + assert(mem_fn(&X::plus)(xp, 17, 25) == 42); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-tuple.C b/gcc/testsuite/g++.dg/cpp0x/variadic-tuple.C new file mode 100644 index 0000000..2c298a1 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-tuple.C @@ -0,0 +1,294 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do "run" } +// An implementation of TR1's <tuple> using variadic teplates +// Contributed by Douglas Gregor <doug.gregor@gmail.com> + +#include <string> +#include <cassert> +#include <cstring> + +// Trivial reference_wrapper +template<typename T> +struct reference_wrapper +{ + reference_wrapper(T& x) : ptr(&x) { } + + operator T&() const { return *ptr; } + + T* ptr; +}; + +template<typename T> reference_wrapper<T> ref(T& x) { return x; } +template<typename T> reference_wrapper<const T> cref(const T& x) { return x; } + +// Simple type-traits we'll need +template<typename T> +struct add_reference +{ + typedef T& type; +}; + +template<typename T> +struct add_reference<T&> +{ + typedef T& type; +}; + +template<typename T, typename U> +struct is_same +{ + static const bool value = false; +}; + +template<typename T> +struct is_same<T, T> +{ + static const bool value = true; +}; + +// For creating the constructor parameters of tuple<> +template<typename T> +struct add_const_reference +{ + typedef const T& type; +}; + +template<typename T> +struct add_const_reference<T&> +{ + typedef T& type; +}; + +// 6.1.3 Class template tuple +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 + + tuple(typename add_const_reference<Head>::type v, + typename add_const_reference<Tail>::type... vtail) + : m_head(v), inherited(vtail...) { } + + 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 T> +struct make_tuple_result +{ + typedef T type; +}; + +template<typename T> +struct make_tuple_result<reference_wrapper<T> > +{ + typedef T& type; +}; + +// 6.1.3.2 Tuple creation functions +struct ignore_t { + template<typename T> ignore_t& operator=(const T&) { return *this; } +} ignore; + +template<typename... Values> +tuple<typename make_tuple_result<Values>::type...> +make_tuple(const Values&... values) +{ + return tuple<typename make_tuple_result<Values>::type...>(values...); +} + +template<typename... Values> +tuple<Values&...> tie(Values&... values) +{ + return tuple<Values&...>(values...); +} + +// 6.1.3.3 Tuple helper classes +template<typename Tuple> +struct tuple_size; + +template<> +struct tuple_size<tuple<> > +{ + static const std::size_t value = 0; +}; + +template<typename Head, typename... Tail> +struct tuple_size<tuple<Head, Tail...> > +{ + static const std::size_t value = 1 + tuple_size<tuple<Tail...> >::value; +}; + +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; +}; + +// 6.1.3.4 Element access +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 typename add_reference<Element>::type RJ; + typedef typename add_const_reference<Element>::type PJ; + typedef get_impl<I-1, tuple<Values...> > Next; + + public: + static RJ get(tuple<Head, Values...>& t) + { return Next::get(t.tail()); } + + static PJ get(const tuple<Head, Values...>& t) + { return Next::get(t.tail()); } +}; + +template<typename Head, typename... Values> +class get_impl<0, tuple<Head, Values...> > +{ + typedef typename add_reference<Head>::type RJ; + typedef typename add_const_reference<Head>::type PJ; + + public: + static RJ get(tuple<Head, Values...>& t) { return t.head(); } + static PJ get(const tuple<Head, Values...>& t) { return t.head(); } +}; + +template<int I, typename... Values> +typename add_reference< + typename tuple_element<I, tuple<Values...> >::type + >::type +get(tuple<Values...>& t) +{ + return get_impl<I, tuple<Values...> >::get(t); +} + +template<int I, typename... Values> +typename add_const_reference< + typename tuple_element<I, tuple<Values...> >::type + >::type +get(const tuple<Values...>& t) +{ + return get_impl<I, tuple<Values...> >::get(t); +} + +// 6.1.3.5 Relational operators +inline bool operator==(const tuple<>&, const tuple<>&) { return true; } + +template<typename T, typename... TTail, typename U, typename... UTail> +bool operator==(const tuple<T, TTail...>& t, const tuple<U, UTail...>& u) +{ + return t.head() == u.head() && t.tail() == u.tail(); +} + +template<typename... TValues, typename... UValues> +bool operator!=(const tuple<TValues...>& t, const tuple<UValues...>& u) +{ + return !(t == u); +} + +inline bool operator<(const tuple<>&, const tuple<>&) { return false; } + +template<typename T, typename... TTail, typename U, typename... UTail> +bool operator<(const tuple<T, TTail...>& t, const tuple<U, UTail...>& u) +{ + return (t.head() < u.head() || + (!(t.head() < u.head()) && t.tail() < u.tail())); +} + +template<typename... TValues, typename... UValues> +bool operator>(const tuple<TValues...>& t, const tuple<UValues...>& u) +{ + return u < t; +} + +template<typename... TValues, typename... UValues> +bool operator<=(const tuple<TValues...>& t, const tuple<UValues...>& u) +{ + return !(u < t); +} + +template<typename... TValues, typename... UValues> +bool operator>=(const tuple<TValues...>& t, const tuple<UValues...>& u) +{ + return !(t < u); +} + +int a0[tuple_size<tuple<> >::value == 0? 1 : -1]; +int a1[tuple_size<tuple<int, float, double> >::value == 3? 1 : -1]; +int a2a[is_same<tuple_element<0, tuple<int, float, double> >::type, int> + ::value? 1 : -1]; +int a2b[is_same<tuple_element<1, tuple<int, float, double> >::type, float> + ::value? 1 : -1]; +int a2c[is_same<tuple_element<2, tuple<int, float, double> >::type, double> + ::value? 1 : -1]; + +int main() +{ + tuple<> t0; + tuple<int> t1(1); + tuple<int, float> t2(1, 3.14159f); + tuple<int, float, const char*> t3a(1, 3.14159f, "Hello, world!"); + tuple<long, double, std::string> t3b(t3a); + t3b = t3a; + // t3a = t3b; DPG: triggers an error, as it should. + + tuple<int, float, std::string> t3c = + make_tuple(17, 2.718281828, std::string("Fun")); + + int seventeen = 17; + double pi = 3.14159; + tuple<int&, double&> seventeen_pi = make_tuple(ref(seventeen), ref(pi)); + tuple<int&, const double&> seventeen_pi2 = + make_tuple(ref(seventeen), cref(pi)); + tuple<int&, double&> seventeen_pi_tied = tie(seventeen, pi); + assert(get<0>(t3a) == 1); + assert(get<1>(t3a) == 3.14159f); + assert(std::strcmp(get<2>(t3a), "Hello, world!") == 0); + + assert(t3a == t3b); + assert(!(t3a != t3b)); + assert(!(t3a < t3b)); + assert(!(t3a > t3b)); + assert(t3a <= t3b && t3b <= t3a); + assert(t3a >= t3b && t3b >= t3a); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic1.C b/gcc/testsuite/g++.dg/cpp0x/variadic1.C new file mode 100644 index 0000000..f87d53c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic1.C @@ -0,0 +1,10 @@ +// { dg-options "-std=gnu++0x" } +template<typename...> +class tuple; + +template<typename... Args> +class tuple { }; + +template<typename T1, class... Args> +class tuple1p { }; + diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic10.C b/gcc/testsuite/g++.dg/cpp0x/variadic10.C new file mode 100644 index 0000000..5f73eba --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic10.C @@ -0,0 +1,22 @@ +// { dg-options "-std=gnu++0x" } +template<typename T1, typename T2> +struct pair {}; + +template<typename... Args> +struct tuple { + static const int value = 0; +}; + +template<> +struct tuple<pair<int, float> > { }; + +template<typename... Outer> +struct X { + template<typename... Inner> + struct Y + { + typedef tuple<pair<Outer, Inner>...> type; // { dg-error "mismatched argument pack lengths" } + }; +}; + +X<int, double>::Y<short, char, double>::type honk; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic11.C b/gcc/testsuite/g++.dg/cpp0x/variadic11.C new file mode 100644 index 0000000..3c27de0 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic11.C @@ -0,0 +1,18 @@ +// { dg-options "-std=gnu++0x" } +template<typename...> struct count; + +template<> +struct count<> { + static const int value = 0; +}; + +template<typename T, typename... Args> +struct count<T, Args...> { + static const int value = 1 + count<Args...>::value; +}; + +int a0[count<>::value == 0? 1 : -1]; +int a1[count<char>::value == 1? 1 : -1]; +int a2[count<char, short>::value == 2? 1 : -1]; +int a3[count<char, short, int>::value == 3? 1 : -1]; +int a4[count<char, short, int, long>::value == 4? 1 : -1]; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic12.C b/gcc/testsuite/g++.dg/cpp0x/variadic12.C new file mode 100644 index 0000000..30108c9 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic12.C @@ -0,0 +1,42 @@ +// { dg-options "-std=gnu++0x" } +// A tuple type +template<typename... Args> struct tuple { }; + +// Determine if two types are the same +template<typename T, typename U> +struct is_same { + static const bool value = false; +}; + +template<typename T> +struct is_same<T, T> { + static const bool value = true; +}; + +// Append 'T' to the end of Tuple +template<typename T, typename Tuple> +struct append_to_tuple; + +template<typename T, typename... Args> +struct append_to_tuple<T, tuple<Args...> > { + typedef tuple<Args..., T> type; +}; + +// Reverse a sequence of arguments (and return the result as a tuple) +template<typename... Args> struct reverse; + +template<typename T, typename... Args> +struct reverse<T, Args...> { + typedef typename append_to_tuple<T, typename reverse<Args...>::type>::type + type; +}; + +template<> +struct reverse<> { + typedef tuple<> type; +}; + +int a0[is_same<reverse<>::type, tuple<> >::value? 1 : -1]; +int a1[is_same<reverse<int>::type, tuple<int> >::value? 1 : -1]; +int a2[is_same<reverse<char, int>::type, tuple<int, char> >::value? 1 : -1]; +int a3[is_same<reverse<char, int, long>::type, tuple<long, int, char> >::value? 1 : -1]; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic13.C b/gcc/testsuite/g++.dg/cpp0x/variadic13.C new file mode 100644 index 0000000..7794e8a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic13.C @@ -0,0 +1,19 @@ +// { dg-options "-std=gnu++0x" } +template<typename... Args> struct tuple1 { }; +template<typename... Args> struct tuple2 { }; + +template<typename T, typename U> +struct same_tuple_args { + static const bool value = false; +}; + +template<typename... Args> +struct same_tuple_args<tuple1<Args...>, tuple2<Args...> > { + static const bool value = true; +}; + +int same0[same_tuple_args<tuple1<>, tuple2<> >::value? 1 : -1]; +int same1[same_tuple_args<tuple1<int>, tuple2<int> >::value? 1 : -1]; +int same2[same_tuple_args<tuple1<float, int>, tuple2<float, int> >::value? 1 : -1]; +int diff0[!same_tuple_args<tuple1<>, tuple2<int> >::value? 1 : -1]; +int diff1[!same_tuple_args<tuple1<int, float>, tuple2<float, int> >::value? 1 : -1]; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic14.C b/gcc/testsuite/g++.dg/cpp0x/variadic14.C new file mode 100644 index 0000000..3c1bb0d --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic14.C @@ -0,0 +1,21 @@ +// { dg-options "-std=gnu++0x" } +template<typename R, typename... ArgTypes> +struct make_function_type +{ + typedef R type(ArgTypes...); +}; + +template<typename T, typename U> +struct is_same { + static const bool value = false; +}; + +template<typename T> +struct is_same<T, T> { + static const bool value = true; +}; + +int a0[is_same<make_function_type<int>::type, int()>::value? 1 : -1]; +int a1[is_same<make_function_type<int, float>::type, int(float)>::value? 1 : -1]; +int a2[is_same<make_function_type<int, float>::type, int(float)>::value? 1 : -1]; +int a3[is_same<make_function_type<int, float, double>::type, int(float, double)>::value? 1 : -1]; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic15.C b/gcc/testsuite/g++.dg/cpp0x/variadic15.C new file mode 100644 index 0000000..68786cb --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic15.C @@ -0,0 +1,21 @@ +// { dg-options "-std=gnu++0x" } +template<typename R, typename... ArgTypes> +struct make_function_type +{ + typedef R type(const ArgTypes&...); +}; + +template<typename T, typename U> +struct is_same { + static const bool value = false; +}; + +template<typename T> +struct is_same<T, T> { + static const bool value = true; +}; + +int a0[is_same<make_function_type<int>::type, int()>::value? 1 : -1]; +int a1[is_same<make_function_type<int, float>::type, int(const float&)>::value? 1 : -1]; +int a2[is_same<make_function_type<int, float>::type, int(const float&)>::value? 1 : -1]; +int a3[is_same<make_function_type<int, float, double>::type, int(const float&, double const&)>::value? 1 : -1]; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic16.C b/gcc/testsuite/g++.dg/cpp0x/variadic16.C new file mode 100644 index 0000000..001919d --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic16.C @@ -0,0 +1,21 @@ +// { dg-options "-std=gnu++0x" } +template<typename R, typename... ArgTypes> +struct make_function_type +{ + typedef R type(const ArgTypes&... args); +}; + +template<typename T, typename U> +struct is_same { + static const bool value = false; +}; + +template<typename T> +struct is_same<T, T> { + static const bool value = true; +}; + +int a0[is_same<make_function_type<int>::type, int()>::value? 1 : -1]; +int a1[is_same<make_function_type<int, float>::type, int(const float&)>::value? 1 : -1]; +int a2[is_same<make_function_type<int, float>::type, int(const float&)>::value? 1 : -1]; +int a3[is_same<make_function_type<int, float, double>::type, int(const float&, double const&)>::value? 1 : -1]; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic17.C b/gcc/testsuite/g++.dg/cpp0x/variadic17.C new file mode 100644 index 0000000..986721b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic17.C @@ -0,0 +1,21 @@ +// { dg-options "-std=gnu++0x" } +template<typename R, typename... ArgTypes> +struct make_function_type +{ + typedef R type(const ArgTypes&......); +}; + +template<typename T, typename U> +struct is_same { + static const bool value = false; +}; + +template<typename T> +struct is_same<T, T> { + static const bool value = true; +}; + +int a0[is_same<make_function_type<int>::type, int(...)>::value? 1 : -1]; +int a1[is_same<make_function_type<int, float>::type, int(const float&...)>::value? 1 : -1]; +int a2[is_same<make_function_type<int, float>::type, int(const float&,...)>::value? 1 : -1]; +int a3[is_same<make_function_type<int, float, double>::type, int(const float&, double const&...)>::value? 1 : -1]; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic18.C b/gcc/testsuite/g++.dg/cpp0x/variadic18.C new file mode 100644 index 0000000..147ed8e --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic18.C @@ -0,0 +1,47 @@ +// { dg-options "-std=gnu++0x" } +template<typename...> class tuple { }; + +template<typename T, template<typename T> class... Metafunctions> +struct apply_all +{ + typedef tuple<typename Metafunctions<T>::type...> type; +}; + +template<typename T, typename U> +struct is_same { + static const bool value = false; +}; + +template<typename T> +struct is_same<T, T> { + static const bool value = true; +}; + +template<typename T> +struct add_pointer { + typedef T* type; +}; + +template<typename T> +struct add_pointer<T&> +{ + typedef T& type; +}; + +template<typename T> +struct add_reference { + typedef T& type; +}; + +template<typename T> +struct add_reference<T&> +{ + typedef T& type; +}; + +int a0[is_same<apply_all<int>::type,tuple<> >::value? 1 : -1]; +int a1[is_same<apply_all<int, add_pointer>::type,tuple<int*> >::value? 1 : -1]; +int a2[is_same<apply_all<int, add_pointer, add_reference>::type,tuple<int*, int&> >::value? 1 : -1]; +int a3[is_same<apply_all<int&, add_pointer, add_reference>::type,tuple<int&, int&> >::value? 1 : -1]; + + diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic19.C b/gcc/testsuite/g++.dg/cpp0x/variadic19.C new file mode 100644 index 0000000..92e7a95 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic19.C @@ -0,0 +1,19 @@ +// { dg-options "-std=gnu++0x" } +template<typename... Args> +struct tuple { + static const int value = 0; +}; + +template<typename T, template<class T> class... Metafunctions> +struct tuple<Metafunctions<T>...> { + static const int value = 1; +}; + +template<typename T> struct add_pointer; +template<typename T> struct add_reference; + +int a0[tuple<int, float>::value == 0? 1 : -1]; +int a1[tuple<add_pointer<int>, add_pointer<float> >::value == 0? 1 : -1]; +int a2[tuple<>::value == 0? 1 : -1]; +int a3[tuple<add_pointer<int> >::value == 1? 1 : -1]; +int a4[tuple<add_pointer<int>, add_reference<int> >::value == 1? 1 : -1]; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic2.C b/gcc/testsuite/g++.dg/cpp0x/variadic2.C new file mode 100644 index 0000000..d62a542 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic2.C @@ -0,0 +1,17 @@ +// { dg-options "-std=gnu++0x" } +template<typename... Args = int> // { dg-error "default argument" } +class tuple2; + +template<typename... = int> // { dg-error "default argument" } +class tuple3; + +template<typename T1, typename T2, typename... Rest> +struct two_or_more {}; // { dg-error "provided for" } + +typedef two_or_more<int> bad; // { dg-error "2 or more" } +// { dg-error "invalid type" "" { target *-*-* } 11 } + +void f() +{ + two_or_more<int, float> z = 5; // { dg-error "two_or_more<int, float>" } +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic20.C b/gcc/testsuite/g++.dg/cpp0x/variadic20.C new file mode 100644 index 0000000..06204c7 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic20.C @@ -0,0 +1,47 @@ +// { dg-options "-std=gnu++0x" } +template<typename T> struct add_pointer; +template<typename T> struct add_reference; + +template<template<class T> class... Metafunctions> +struct metatuple { + static const int value = 0; +}; + +template<> +struct metatuple<add_pointer> { + static const int value = 1; +}; + +template<template<class T> class Meta> +struct metatuple<Meta, Meta> { // { dg-error "candidates" } + static const int value = 2; +}; + +template<template<class T> class... Metafunctions> +struct metatuple<add_pointer, Metafunctions...> { // { dg-error "" } + static const int value = 3; +}; + +template<template<class T> class First, + template<class T> class... Metafunctions> +struct metatuple<First, Metafunctions...> { // { dg-error "struct" } + static const int value = 4; +}; + +template<template<class T> class First, + template<class T> class Second, + template<class T> class... Metafunctions> +struct metatuple<First, Second, Metafunctions...> { // { dg-error "struct" } + static const int value = 5; +}; + +int a0[metatuple<>::value == 0? 1 : -1]; +int a1[metatuple<add_pointer>::value == 1? 1 : -1]; +int a2a[metatuple<add_pointer, add_pointer>::value == 2? 1 : -1]; // { dg-error "ambiguous" } +int a2b[metatuple<add_reference, add_reference>::value == 2? 1 : -1]; +int a3[metatuple<add_pointer, add_reference>::value == 3? 1 : -1]; // { dg-error "ambiguous" } +int a4[metatuple<add_reference>::value == 4? 1 : -1]; +int a5[metatuple<add_reference, add_pointer>::value == 5? 1 : -1]; + +// { dg-error "incomplete" "" { target *-*-* } 40 } +// { dg-error "incomplete" "" { target *-*-* } 42 } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic21.C b/gcc/testsuite/g++.dg/cpp0x/variadic21.C new file mode 100644 index 0000000..b65e995 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic21.C @@ -0,0 +1,7 @@ +// { dg-options "-std=gnu++0x" } +template<typename T, int... Dims> +struct array { }; + +array<int> a0; +array<int, 1> a1; +array<int, 1, 2, 3, 4> a1234; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic22.C b/gcc/testsuite/g++.dg/cpp0x/variadic22.C new file mode 100644 index 0000000..1d26e40 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic22.C @@ -0,0 +1,21 @@ +// { dg-options "-std=gnu++0x" } +template<typename R, typename... ArgTypes> +struct make_function_type +{ + typedef R type(ArgTypes... args); +}; + +template<typename T, typename U> +struct is_same { + static const bool value = false; +}; + +template<typename T> +struct is_same<T, T> { + static const bool value = true; +}; + +int a0[is_same<make_function_type<int>::type, int()>::value? 1 : -1]; +int a1[is_same<make_function_type<int, float>::type, int(float)>::value? 1 : -1]; +int a2[is_same<make_function_type<int, float>::type, int(float)>::value? 1 : -1]; +int a3[is_same<make_function_type<int, float, double>::type, int(float, double const)>::value? 1 : -1]; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic23.C b/gcc/testsuite/g++.dg/cpp0x/variadic23.C new file mode 100644 index 0000000..43309a1 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic23.C @@ -0,0 +1,25 @@ +// { dg-options "-std=gnu++0x" } +template<typename T, int... Dims> +struct array { + static const int value = 0; +}; + +template<> +struct array<int, 17> { + static const int value = 1; +}; + +template<int... Dims> +struct array<float, 1, Dims...> { + static const int value = 2; +}; + +template<typename T, int... Dims> +struct array<T, 1, Dims...> { + static const int value = 3; +}; + +int a0[array<int>::value == 0? 1 : -1]; +int a1[array<int, 17>::value == 1? 1 : -1]; +int a2[array<float, 1, 2, 3>::value == 2? 1 : -1]; +int a3[array<double, 1, 2, 3>::value == 3? 1 : -1]; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic24.C b/gcc/testsuite/g++.dg/cpp0x/variadic24.C new file mode 100644 index 0000000..6ef8e8a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic24.C @@ -0,0 +1,6 @@ +// { dg-options "-std=gnu++0x" } +template<typename T, T... Values> +struct vector_c { }; + +vector_c<int, 17, 42> intvec; +vector_c<char, 'a', 'b', 'c'> charvec; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic25.C b/gcc/testsuite/g++.dg/cpp0x/variadic25.C new file mode 100644 index 0000000..6589e7f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic25.C @@ -0,0 +1,16 @@ +// { dg-options "-std=gnu++0x" } +template<int... Values> +struct sum; + +template<> +struct sum<> { + static const int value = 0; +}; + +template<int Value, int... Values> +struct sum<Value, Values...> { + static const int value = Value + sum<Values...>::value; +}; + +int a0[sum<>::value == 0? 1 : -1]; +int a1[sum<1, 2, 3, 4, 5>::value == 15? 1 : -1]; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic26.C b/gcc/testsuite/g++.dg/cpp0x/variadic26.C new file mode 100644 index 0000000..7f9f6bc --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic26.C @@ -0,0 +1,24 @@ +// { dg-options "-std=gnu++0x" } +template<template<int, int> class Meta, int Initial, int... Values> +struct accumulate { + static const int value = Initial; +}; + +template<template<int, int> class Meta, int Initial, int Value, int... Rest> +struct accumulate<Meta, Initial, Value, Rest...> { + static const int value = + Meta<Value, accumulate<Meta, Initial, Rest...>::value>::value; +}; + +template<int X, int Y> +struct sum { + static const int value = X + Y; +}; + +template<int X, int Y> +struct prod { + static const int value = X * Y; +}; + +int a0[accumulate<sum,0,1,2,3,4,5>::value == 15? 1 : -1]; +int a1[accumulate<prod,1,1,2,3,4,5>::value == 120? 1 : -1]; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic27.C b/gcc/testsuite/g++.dg/cpp0x/variadic27.C new file mode 100644 index 0000000..45a897c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic27.C @@ -0,0 +1,22 @@ +// { dg-options "-std=gnu++0x" } +template<typename Signature> +struct function_traits; + +template<typename R, typename... ArgTypes> +struct function_traits<R(ArgTypes...)> { + typedef R result_type; +}; + +template<typename T, typename U> +struct same_type { + static const bool value = false; +}; + +template<typename T> +struct same_type<T, T> { + static const bool value = true; +}; + +int a0[same_type<function_traits<int()>::result_type, int>::value? 1 : -1]; +int a1[same_type<function_traits<int(float)>::result_type, int>::value? 1 : -1]; +int a2[same_type<function_traits<int(double, char)>::result_type, int>::value? 1 : -1]; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic28.C b/gcc/testsuite/g++.dg/cpp0x/variadic28.C new file mode 100644 index 0000000..167088b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic28.C @@ -0,0 +1,25 @@ +// { dg-options "-std=gnu++0x" } +template<typename Signature> +struct function_traits; + +template<typename R, typename... ArgTypes> +struct function_traits<R(ArgTypes......)> { + typedef R result_type; +}; + +template<typename T, typename U> +struct same_type { + static const bool value = false; +}; + +template<typename T> +struct same_type<T, T> { + static const bool value = true; +}; + +int a0[same_type<function_traits<int(double, char...)>::result_type, int>::value? 1 : -1]; +int a1[same_type<function_traits<int(double, char,...)>::result_type, int>::value? 1 : -1]; +int a2[same_type<function_traits<int(char,...)>::result_type, int>::value? 1 : -1]; +int a3[same_type<function_traits<int(...)>::result_type, int>::value? 1 : -1]; +int a4[same_type<function_traits<int(double x, char...)>::result_type, int>::value? 1 : -1]; +int a5[same_type<function_traits<int(double, char y...)>::result_type, int>::value? 1 : -1]; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic29.C b/gcc/testsuite/g++.dg/cpp0x/variadic29.C new file mode 100644 index 0000000..aaed595 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic29.C @@ -0,0 +1,35 @@ +// { dg-options "-std=gnu++0x" } +template<typename Signature> +struct function_traits; + +template<typename R, typename... ArgTypes> +struct function_traits<R(ArgTypes...)> { + typedef R result_type; +}; + +template<typename R, typename Class, typename... ArgTypes> +struct function_traits<R (Class::*)(ArgTypes...)> { + typedef R result_type; +}; + +template<typename R, typename Class, typename... ArgTypes> +struct function_traits<R (Class::*)(ArgTypes...) const> { + typedef R result_type; +}; + +template<typename T, typename U> +struct same_type { + static const bool value = false; +}; + +template<typename T> +struct same_type<T, T> { + static const bool value = true; +}; + +struct X {}; + +int a0[same_type<function_traits<int (X::*)()>::result_type, int>::value? 1 : -1]; +int a1[same_type<function_traits<int (X::*)(float)>::result_type, int>::value? 1 : -1]; +int a2[same_type<function_traits<int (X::*)(double, char)>::result_type, int>::value? 1 : -1]; +int a3[same_type<function_traits<int (X::*)(double, char) const>::result_type, int>::value? 1 : -1]; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic3.C b/gcc/testsuite/g++.dg/cpp0x/variadic3.C new file mode 100644 index 0000000..42ba8ab --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic3.C @@ -0,0 +1,10 @@ +// { dg-options "-std=gnu++0x" } +template<typename... Args> +class tuple {}; + +void f() +{ + tuple<> x; + tuple<int> y; + tuple<int, float> z; +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic30.C b/gcc/testsuite/g++.dg/cpp0x/variadic30.C new file mode 100644 index 0000000..66cbe9f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic30.C @@ -0,0 +1,11 @@ +// { dg-options "-std=gnu++0x" } +template<typename... T> +void eat(T...); + +void f() +{ + eat(); + eat(1); + eat(1, 2); + eat(17, 3.14159, "Hello, World!"); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic31.C b/gcc/testsuite/g++.dg/cpp0x/variadic31.C new file mode 100644 index 0000000..eacf568 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic31.C @@ -0,0 +1,11 @@ +// { dg-options "-std=gnu++0x" } +template<typename... T> +void eat(T...) { } + +void f() +{ + eat(); + eat(1); + eat(1, 2); + eat(17, 3.14159, "Hello, World!"); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic32.C b/gcc/testsuite/g++.dg/cpp0x/variadic32.C new file mode 100644 index 0000000..c5bee55 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic32.C @@ -0,0 +1,11 @@ +// { dg-options "-std=gnu++0x" } +template<typename... T> +void eat(const T&...) { } + +void f() +{ + eat(); + eat(1); + eat(1, 2); + eat(17, 3.14159, "Hello, World!"); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic33.C b/gcc/testsuite/g++.dg/cpp0x/variadic33.C new file mode 100644 index 0000000..5784be8 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic33.C @@ -0,0 +1,16 @@ +// { dg-options "-std=gnu++0x" } +void print_all() {} + +template<typename T, typename... Rest> +void print_all(const T& t, const Rest&... rest) +{ + print_all(rest...); +} + +void f() +{ + print_all(); + print_all(1); + print_all(1, 3.14159); + print_all("Hello, World!", 17, 3.14159); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic34.C b/gcc/testsuite/g++.dg/cpp0x/variadic34.C new file mode 100644 index 0000000..5eee3f1 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic34.C @@ -0,0 +1,11 @@ +// { dg-options "-std=gnu++0x" } +template<int I, typename... Args> +void get_ith(const Args&... args); + +void f() +{ + get_ith<1>(1, 2, 3); + get_ith<1, int>(1, 2.0, 'x'); + get_ith<1, int, double>(1, 2.0, 'x'); + get_ith<1, int, double, char>(1, 2.0, 'x'); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic35.C b/gcc/testsuite/g++.dg/cpp0x/variadic35.C new file mode 100644 index 0000000..cd6ba2b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic35.C @@ -0,0 +1,9 @@ +// { dg-options "-std=gnu++0x" } +template<int I, typename... Args> +void get_ith(const Args&... args); + +void f() +{ + get_ith<1, float>(1, 2.0, 'x'); + get_ith<1, int, double, char, int>(1, 2.0, 'x'); // { dg-error "no matching function" } +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic36.C b/gcc/testsuite/g++.dg/cpp0x/variadic36.C new file mode 100644 index 0000000..370d475 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic36.C @@ -0,0 +1,15 @@ +// { dg-options "-std=gnu++0x" } +template<typename T, typename... Args> +void f(const T&, const Args&... args) +{ + f(args); // { dg-error "packs not expanded" } +} + +template<typename... Values> +struct tuple_base { }; + +template<typename... Values> +struct tuple : tuple_base<Values> { }; // { dg-error "packs not expanded" } + +// { dg-error "args" "" { target *-*-* } 5 } +// { dg-error "Values" "" { target *-*-* } 12 } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic37.C b/gcc/testsuite/g++.dg/cpp0x/variadic37.C new file mode 100644 index 0000000..a6e5f61 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic37.C @@ -0,0 +1,10 @@ +// { dg-options "-std=gnu++0x" } +template<typename... Values> +struct tuple +{ + static const __SIZE_TYPE__ length = sizeof...(Values); +}; + +int a0[tuple<>::length == 0? 1 : -1]; +int a1[tuple<int>::length == 1? 1 : -1]; +int a2[tuple<int, float>::length == 2? 1 : -1]; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic38.C b/gcc/testsuite/g++.dg/cpp0x/variadic38.C new file mode 100644 index 0000000..e4ae4a6 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic38.C @@ -0,0 +1,6 @@ +// { dg-options "-std=gnu++0x" } +template<int... Values> +struct int_vec {}; + +template<int... Values> +struct int_vec<0, (Values+1)...> {}; // { dg-error "involves template parameter" } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic39.C b/gcc/testsuite/g++.dg/cpp0x/variadic39.C new file mode 100644 index 0000000..bd656ba --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic39.C @@ -0,0 +1,13 @@ +// { dg-options "-std=gnu++0x" } +template<typename... Args> +struct tuple {}; + +template<typename T, typename... Args> +struct tuple<Args..., T> { }; // { dg-error "end" } + + +template<int... Values> +struct int_vec { }; + +template<int I, int... Values> +struct int_vec<Values..., I> { }; // { dg-error "end" } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic4.C b/gcc/testsuite/g++.dg/cpp0x/variadic4.C new file mode 100644 index 0000000..6c15a6d --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic4.C @@ -0,0 +1,15 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } +template<typename... Args> +class tuple {}; + +void f_none(tuple<>) {} +void f_one(tuple<int>) {} +void f_two(tuple<int, float>) {} +void f_nested(tuple<int, tuple<double, char>, float>) { } + + +// { dg-final { scan-assembler "_Z6f_none5tupleIE" } } +// { dg-final { scan-assembler "_Z5f_one5tupleIiE" } } +// { dg-final { scan-assembler "_Z5f_two5tupleIifE" } } +// { dg-final { scan-assembler "_Z8f_nested5tupleIiS_IdcEfE" } } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic40.C b/gcc/testsuite/g++.dg/cpp0x/variadic40.C new file mode 100644 index 0000000..6cc9273 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic40.C @@ -0,0 +1,3 @@ +// { dg-options "-std=gnu++0x" } +template<typename... Values, typename T> +struct backward_tuple {}; // { dg-error "end" } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic41.C b/gcc/testsuite/g++.dg/cpp0x/variadic41.C new file mode 100644 index 0000000..d209766 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic41.C @@ -0,0 +1,3 @@ +// { dg-options "-std=gnu++0x" } +template<typename... Args> +void f(const Args&... args, int oops); // { dg-error "end" } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic42.C b/gcc/testsuite/g++.dg/cpp0x/variadic42.C new file mode 100644 index 0000000..4c6c767 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic42.C @@ -0,0 +1,12 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } +template<typename... Args> +void f(Args...) { } + +void g() +{ + f<int*, float*, double*>(0, 0, 0); + f<int*>(0,0,0); +} +// { dg-final { scan-assembler "_Z1fIPiPfPdEvU10__variadicT_" } } +// { dg-final { scan-assembler "_Z1fIPiiiEvU10__variadicT_" } } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic43.C b/gcc/testsuite/g++.dg/cpp0x/variadic43.C new file mode 100644 index 0000000..fce81ae --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic43.C @@ -0,0 +1,8 @@ +// { dg-options "-std=gnu++0x" } +template<typename... Args> +int f(const Args&...); + +void g() +{ + int (*fp)(const int&, const float&) = &f; +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic44.C b/gcc/testsuite/g++.dg/cpp0x/variadic44.C new file mode 100644 index 0000000..8452a96 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic44.C @@ -0,0 +1,13 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } +template<typename... Args> +int f(const Args&...); + +template<typename T> void g(T) { } + +void h() +{ + g(&f<int, float>); +} + +// { dg-final { scan-assembler "_Z1gIPFiRKiRKfEEvT_"} } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic45.C b/gcc/testsuite/g++.dg/cpp0x/variadic45.C new file mode 100644 index 0000000..c5a66ab --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic45.C @@ -0,0 +1,10 @@ +// { dg-options "-std=gnu++0x" } +template<typename... Args> +int& f(Args...); + +template<typename T1, typename T2> +float& f(T1, T2); + +float& g() { + return f(17, 3.14159); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic46.C b/gcc/testsuite/g++.dg/cpp0x/variadic46.C new file mode 100644 index 0000000..8b81a36 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic46.C @@ -0,0 +1,11 @@ +// { dg-options "-std=gnu++0x" } +template<typename... Args> +int& f(Args&...); + +template<typename... Args> +float& f(const Args&...); + +int& g(int x, float y) +{ + return f(x, y); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic47.C b/gcc/testsuite/g++.dg/cpp0x/variadic47.C new file mode 100644 index 0000000..d80371c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic47.C @@ -0,0 +1,18 @@ +// { dg-options "-std=gnu++0x" } +template<typename T> struct wrap { }; + +template<typename... Args> +int& f(const Args&...); + +template<typename... Args> +float& f(const wrap<Args>&...); + +int& g(int x, float y, double z) +{ + return f(x, y, z); +} + +float& h(wrap<int> x, wrap<float> y, wrap<double> z) +{ + return f(x, y, z); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic48.C b/gcc/testsuite/g++.dg/cpp0x/variadic48.C new file mode 100644 index 0000000..ab3f777 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic48.C @@ -0,0 +1,10 @@ +// { dg-options "-std=gnu++0x" } +template<typename T, typename... Args> +int& f(const T&, Args...); + +template<typename T> +float& f(const T&); + +float& g() { + return f(17); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic49.C b/gcc/testsuite/g++.dg/cpp0x/variadic49.C new file mode 100644 index 0000000..7e2215f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic49.C @@ -0,0 +1,9 @@ +// { dg-options "-std=gnu++0x" } +int& f(...); + +template<typename... Args> +float& f(Args...); + +float& g() { + return f(17, 3.14159); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic5.C b/gcc/testsuite/g++.dg/cpp0x/variadic5.C new file mode 100644 index 0000000..d1f3335 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic5.C @@ -0,0 +1,38 @@ +// { dg-options "-std=gnu++0x" } +template<typename... Args> +struct tuple { + static const int value = 0; +}; + +template<> +struct tuple<> { + static const int value = 1; +}; + +template<> +struct tuple<int> { + static const int value = 2; +}; + + +template<> +struct tuple<int, float> { + static const int value = 3; +}; + +template<typename T> +struct tuple<T, T> { + static const int value = 4; +}; + +template<> +struct tuple<float, float> { + static const int value = 5; +}; + +int a0[tuple<float>::value == 0? 1 : -1]; +int a1[tuple<>::value == 1? 1 : -1]; +int a2[tuple<int>::value == 2? 1 : -1]; +int a3[tuple<int, float>::value == 3? 1 : -1]; +int a4[tuple<int, int>::value == 4? 1 : -1]; +int a5[tuple<float, float>::value == 5? 1 : -1]; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic50.C b/gcc/testsuite/g++.dg/cpp0x/variadic50.C new file mode 100644 index 0000000..a2c3b7c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic50.C @@ -0,0 +1,9 @@ +// { dg-options "-std=gnu++0x" } +int& f(int, double, ...); + +template<typename... Args> +float& f(Args...); + +float& g() { + return f(17, 3.14159, 3); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic51.C b/gcc/testsuite/g++.dg/cpp0x/variadic51.C new file mode 100644 index 0000000..e2e2d63 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic51.C @@ -0,0 +1,10 @@ +// { dg-options "-std=gnu++0x" } +template<typename T1, typename T2> +float& f(T1, T2); + +template<typename... Args> +int& f(Args...); + +float& g() { + return f(17, 3.14159); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic52.C b/gcc/testsuite/g++.dg/cpp0x/variadic52.C new file mode 100644 index 0000000..12b121f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic52.C @@ -0,0 +1,7 @@ +// { dg-options "-std=gnu++0x" } +template<typename T, T... Values> +struct vector_c { }; + +vector_c<int, 1, 2, 3> v1; +vector_c<char, 'a', 'b', 'c'> v2; +vector_c<long, 1u, 2, 3l> v3; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic53.C b/gcc/testsuite/g++.dg/cpp0x/variadic53.C new file mode 100644 index 0000000..09a3879 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic53.C @@ -0,0 +1,17 @@ +// { dg-options "-std=gnu++0x" } +template<typename F, typename... BoundArgs> +class bound_functor +{ + public: + typedef typename F::result_type result_type; + + template<typename... Args> + typename F::result_type operator()(Args&... args); +}; + +template<typename F, typename... BoundArgs> +template<typename... Args> +typename F::result_type +bound_functor<F, BoundArgs...>::operator()(Args&... args) +{ +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic54.C b/gcc/testsuite/g++.dg/cpp0x/variadic54.C new file mode 100644 index 0000000..db750d7 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic54.C @@ -0,0 +1,12 @@ +// { dg-options "-std=gnu++0x" } +template<typename F, typename... BoundArgs> +class bound_functor +{ + public: + bound_functor(); +}; + +template<typename F, typename... BoundArgs> +bound_functor<F, BoundArgs...>::bound_functor() +{ +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic55.C b/gcc/testsuite/g++.dg/cpp0x/variadic55.C new file mode 100644 index 0000000..b9c8cff --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic55.C @@ -0,0 +1,12 @@ +// { dg-options "-std=gnu++0x" } +template<typename F, typename... BoundArgs> +class bound_functor +{ + public: + bound_functor(const BoundArgs&... bound_args); +}; + +template<typename F, typename... BoundArgs> +bound_functor<F, BoundArgs...>::bound_functor(const BoundArgs&...) +{ +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic56.C b/gcc/testsuite/g++.dg/cpp0x/variadic56.C new file mode 100644 index 0000000..77846e5 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic56.C @@ -0,0 +1,19 @@ +// { dg-options "-std=gnu++0x" } +template<typename... Elements> +struct tuple { }; + +template<typename T, typename... Elements> +struct tuple<T, Elements...> { + int foo(); +}; + +template<typename T, typename... Elements> +struct tuple<T*, Elements...> { + int bar(); +}; + +template<typename T, typename... Elements> +int tuple<T, Elements...>::foo() { return 0; } + +template<typename T, typename... Elements> +int tuple<T*, Elements...>::bar() { return 0; } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic57.C b/gcc/testsuite/g++.dg/cpp0x/variadic57.C new file mode 100644 index 0000000..9833b1b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic57.C @@ -0,0 +1,16 @@ +// { dg-options "-std=gnu++0x" } +template<typename T, int... Dims> +struct array { + int foo(); +}; + +template<typename T> +struct array<T, 0> { + int bar(); +}; + +template<typename T, int... Dims> +int array<T, Dims...>::foo() { } + +template<typename T> +int array<T, 0>::bar() { } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic58.C b/gcc/testsuite/g++.dg/cpp0x/variadic58.C new file mode 100644 index 0000000..5da0730 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic58.C @@ -0,0 +1,16 @@ +// { dg-options "-std=gnu++0x" } +#include <typeinfo> + +template<typename... Args> +void foo(Args...) { } + +template<typename... Args> +void bar(Args... args) { + foo(Args()...); + foo(args = args...); + foo(reinterpret_cast<void*>(&args)...); + foo(const_cast<const Args>(args)...); + foo(static_cast<void*>(&args)...); + foo(dynamic_cast<void*>(&args)...); + foo(typeid(Args)...); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic59.C b/gcc/testsuite/g++.dg/cpp0x/variadic59.C new file mode 100644 index 0000000..f0730d3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic59.C @@ -0,0 +1,4 @@ +// { dg-options "-std=gnu++0x" } +template<class T, typename... VarArgs> +void print(T t, VarArgs args); // { dg-error "packs not expanded" } +// { dg-error "VarArgs" "" { target *-*-* } 3 } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic6.C b/gcc/testsuite/g++.dg/cpp0x/variadic6.C new file mode 100644 index 0000000..105550b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic6.C @@ -0,0 +1,12 @@ +// { dg-options "-std=gnu++0x" } +template<typename ... Args> +struct tuple_base {}; + +template<typename ... Args> +struct tuple : public tuple_base<Args...> +{ +}; + +tuple<> zero; +tuple<int> one; +tuple<float, int> two; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic60.C b/gcc/testsuite/g++.dg/cpp0x/variadic60.C new file mode 100644 index 0000000..29c4e29 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic60.C @@ -0,0 +1 @@ +template<typename... Args> class tuple; // { dg-warning "variadic templates" } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic61.C b/gcc/testsuite/g++.dg/cpp0x/variadic61.C new file mode 100644 index 0000000..487f78b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic61.C @@ -0,0 +1,2 @@ +// { dg-options "-pedantic" } +template<typename... Args> class tuple; // { dg-warning "variadic templates" } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic62.C b/gcc/testsuite/g++.dg/cpp0x/variadic62.C new file mode 100644 index 0000000..dfa41f7 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic62.C @@ -0,0 +1,2 @@ +// { dg-options "-pedantic-errors" } +template<typename... Args> class tuple; // { dg-error "variadic templates" } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic63.C b/gcc/testsuite/g++.dg/cpp0x/variadic63.C new file mode 100644 index 0000000..359def1 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic63.C @@ -0,0 +1,2 @@ +// { dg-options "-std=gnu++0x -pedantic" } +template<typename... Args> class tuple; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic64.C b/gcc/testsuite/g++.dg/cpp0x/variadic64.C new file mode 100644 index 0000000..c9212e2 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic64.C @@ -0,0 +1,19 @@ +// { dg-options "-std=gnu++0x" } +template<int... Indexes> + struct _Index_tuple { }; + +template<int _Num, typename _Tuple = _Index_tuple<> > +struct _Build_index_tuple; + +template<int _Num, int... _Indexes> +struct _Build_index_tuple<_Num, _Index_tuple<_Indexes...> > + : _Build_index_tuple<_Num - 1, + _Index_tuple<_Indexes..., sizeof...(_Indexes)> > +{ +}; + +template<int... _Indexes> +struct _Build_index_tuple<0, _Index_tuple<_Indexes...> > +{ + typedef _Index_tuple<_Indexes...> __type; +}; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic65.C b/gcc/testsuite/g++.dg/cpp0x/variadic65.C new file mode 100644 index 0000000..6379da8 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic65.C @@ -0,0 +1,8 @@ +// { dg-options "-std=gnu++0x" } +struct unused; +template<typename T1 = unused, typename T2 = unused, typename T3 = unused, + typename T4 = unused, typename T5 = unused, typename T6 = unused> +struct tuple {}; + +template<typename... Args> +void foo(tuple<Args...>) { } // { dg-error "cannot expand" } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic66.C b/gcc/testsuite/g++.dg/cpp0x/variadic66.C new file mode 100644 index 0000000..5c31ae0 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic66.C @@ -0,0 +1,9 @@ +// { dg-options "-std=gnu++0x" } + +template<typename Result, typename Functor, typename... ArgTypes> +Result bind(Functor, ArgTypes...) { } + +void f() +{ + bind<int>(17, 20, 22); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic67.C b/gcc/testsuite/g++.dg/cpp0x/variadic67.C new file mode 100644 index 0000000..e496bfc --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic67.C @@ -0,0 +1,24 @@ +// { dg-options "-std=gnu++0x" } +template<typename... Elements> struct tuple {}; + +template<typename... Args> +struct nested +{ + typedef tuple<tuple<Args, Args...>...> type; +}; + +template<typename T, typename U> +struct is_same +{ + static const bool value = false; +}; + +template<typename T> +struct is_same<T, T> +{ + static const bool value = true; +}; + +int a0[is_same<nested<int, float>::type, + tuple<tuple<int, int, float>, + tuple<float, int, float> > >::value? 1 : -1]; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic68.C b/gcc/testsuite/g++.dg/cpp0x/variadic68.C new file mode 100644 index 0000000..53d8f2d --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic68.C @@ -0,0 +1,23 @@ +// { dg-do "run" } +// { dg-options "-std=gnu++0x" } +extern "C" void abort(); + +template<typename T, T... Values> +void f(T* expected_values, int n) +{ + if (sizeof...(Values) != n) + abort (); + + T values[] = { Values... }; + for (int i = 0; i < n; ++i) + if (values[i] != expected_values[i]) + abort(); +} + +int main() +{ + int test_arr1[3] = { 1, 2, 3 }; + f<int, 1, 2, 3>(test_arr1, 3); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic69.C b/gcc/testsuite/g++.dg/cpp0x/variadic69.C new file mode 100644 index 0000000..5fe9a19 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic69.C @@ -0,0 +1,34 @@ +// { dg-options "-std=gnu++0x" } +template<typename T> +struct stored_value +{ + explicit stored_value() : value() { } + + explicit stored_value(const T& value) : value(value) { } + + stored_value(int, const T& value) : value(value) { } + + T value; +}; + +template<typename... Values> +struct myclass : public stored_value<Values>... +{ + myclass() { } + + explicit myclass(const Values&... values) + : stored_value<Values>(values)... { } + + explicit myclass(int x, const Values&... values) + : stored_value<Values>(x, values)... { } + +}; + +void f() +{ + int i; + float f; + myclass<int*, float*> ifp1; + myclass<int*, float*> ifp2(&i, &f); + myclass<int*, float*> ifp3(1, &i, &f); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic7.C b/gcc/testsuite/g++.dg/cpp0x/variadic7.C new file mode 100644 index 0000000..3ba37bf --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic7.C @@ -0,0 +1,33 @@ +// { dg-options "-std=gnu++0x" } +template<typename... Args> +struct tuple_base { + static const int value = 0; +}; + +template<> +struct tuple_base<int> { + static const int value = 1; +}; + +template<> +struct tuple_base<int, float> { + static const int value = 2; +}; + +template<> +struct tuple_base<float, int> { + static const int value = 3; +}; + +template<typename... Args> +struct int_tuple : tuple_base<int, Args...> { }; + +template<typename... Args> +struct tuple_int : tuple_base<Args..., int> { }; + +int a0a[int_tuple<int>::value == 0? 1 : -1]; +int a0b[int_tuple<int>::value == 0? 1 : -1]; +int a1a[int_tuple<>::value == 1? 1 : -1]; +int a1b[tuple_int<>::value == 1? 1 : -1]; +int a2[int_tuple<float>::value == 2? 1 : -1]; +int a3[tuple_int<float>::value == 3? 1 : -1]; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic70.C b/gcc/testsuite/g++.dg/cpp0x/variadic70.C new file mode 100644 index 0000000..0bc8e82 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic70.C @@ -0,0 +1,22 @@ +// { dg-do "run" } +// { dg-options "-std=gnu++0x" } +template <typename T, T... Args> struct bomb; + +template <typename T> +struct bomb<T> { + static const T value = 0; +}; + +template <typename T, T v, T... Args> +struct bomb<T, v, Args...> { + static const T value = v + bomb<T, Args...>::value; +}; + +extern "C" void abort(); + +int main() { + bomb<int, 1, 2, 3, 4> b; + if (b.value != 10) + abort(); + return 0; +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic71.C b/gcc/testsuite/g++.dg/cpp0x/variadic71.C new file mode 100644 index 0000000..d4219da --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic71.C @@ -0,0 +1,12 @@ +// { dg-options "-std=gnu++0x" } +template<typename...> struct list {}; + +template<typename Sequence, typename Head> +struct push_front; + +template<typename... Elements, typename Head> +struct push_front<list<Elements...>, Head> { + typedef list<Head, Elements> type; // { dg-error "parameter packs not expanded" } +}; + +// { dg-error "Elements" "" { target *-*-* } 9 } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic72.C b/gcc/testsuite/g++.dg/cpp0x/variadic72.C new file mode 100644 index 0000000..b1a620d --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic72.C @@ -0,0 +1,21 @@ +// { dg-options "-std=gnu++0x" } +struct A {}; +struct B {}; +struct C {}; + +template<typename... Mixins> +struct mixed_up : public Mixins... +{ +}; + +void fA(A); +void fB(B); +void fC(C); + +void g() +{ + mixed_up<A, B, C> m; + fA(m); + fB(m); + fC(m); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic73.C b/gcc/testsuite/g++.dg/cpp0x/variadic73.C new file mode 100644 index 0000000..7bff85b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic73.C @@ -0,0 +1,33 @@ +// { dg-do "run" } +// { dg-options "-std=gnu++0x" } +struct A {}; +struct B {}; +struct C {}; + +template<typename... Exceptions> void f(int idx) throw(Exceptions...) { + if (idx == 0) throw A(); + else if (idx == 1) throw B(); + else if (idx == 2) throw C(); +} + +extern "C" void abort(); + +int main() +{ + try { + f<A, B, C>(0); + abort(); + } catch (A) { + } + try { + f<A, B, C>(1); + abort(); + } catch (B) { + } + try { + f<A, B, C>(2); + abort(); + } catch (C) { + } + return 0; +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic74.C b/gcc/testsuite/g++.dg/cpp0x/variadic74.C new file mode 100644 index 0000000..19b6b11 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic74.C @@ -0,0 +1,26 @@ +// { dg-options "-std=gnu++0x" } +template <class... Types> class A +{ +public: + template <Types... Values> class X { /* ... */ }; // { dg-error "not a valid type for a template constant parameter" } +}; + +template<class... Types> class B +{ +public: + template <Types*... Values> class X { + typename A<Types*...>::template X<Values...> foo; + }; +}; + +int i; +float f; + +A<int*, float*>::X<&i, &f> apple1; +B<int, float>::X<&i, &f> banana1; + +A<int*, float*>::X<&i> apple2; // { dg-error "wrong number of template arguments" } +// { dg-error "invalid type" "" { target *-*-* } 22 } +A<int*, float*>::X<&i, &f, &f> apple3; // { dg-error "wrong number of template arguments" } +// { dg-error "invalid type" "" { target *-*-* } 24 } +A<int, float> apple4; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic75.C b/gcc/testsuite/g++.dg/cpp0x/variadic75.C new file mode 100644 index 0000000..f57f8b3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic75.C @@ -0,0 +1,33 @@ +// { dg-options "-std=gnu++0x" } + +template<typename...> struct tuple { }; + +template<template<typename T> class Meta, typename... Values> +struct apply_all +{ + typedef tuple<typename Meta<Values>::type...> type; +}; + +template<typename T, typename U> +struct is_same { + static const bool value = false; +}; + +template<typename T> +struct is_same<T, T> { + static const bool value = true; +}; + +template<typename T> +struct add_reference { + typedef T& type; +}; + +template<typename T> +struct add_reference<T&> { + typedef T& type; +}; + +static_assert(is_same<apply_all<add_reference, int, int&, float>::type, + tuple<int&, int&, float&> >::value, + "check apply"); diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic8.C b/gcc/testsuite/g++.dg/cpp0x/variadic8.C new file mode 100644 index 0000000..c3a1340 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic8.C @@ -0,0 +1,23 @@ +// { dg-options "-std=gnu++0x" } +template<typename... Args> +struct tuple_base { + static const int value = 0; +}; + +template<> +struct tuple_base<int*> +{ + static const int value = 1; +}; + +template<typename T> +struct tuple_base<T*> +{ + static const int value = 2; +}; + +template<typename... Args> +struct tuple_of_pointers : tuple_base<Args*...> { }; + +int a1[tuple_of_pointers<int>::value == 1? 1 : -1]; +int a2[tuple_of_pointers<float>::value == 2? 1 : -1]; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic9.C b/gcc/testsuite/g++.dg/cpp0x/variadic9.C new file mode 100644 index 0000000..c5db6af --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic9.C @@ -0,0 +1,38 @@ +// { dg-options "-std=gnu++0x" } +template<typename T1, typename T2> +struct pair {}; + +template<typename... Args> +struct tuple { + static const int value = 0; +}; + +template<> +struct tuple<pair<int, float> > { + static const int value = 1; +}; + +template<typename U> +struct tuple<pair<int, U> > { + static const int value = 2; +}; + +template<typename T, typename U> +struct tuple<pair<T, U>, pair<T, U> > { + static const int value = 3; +}; + + +template<typename... Outer> +struct X { + template<typename... Inner> + struct Y + { + typedef tuple<pair<Outer, Inner>...> type; + }; +}; + +int a0[X<int, double>::Y<short, char>::type::value == 0? 1 : -1]; +int a1[X<int>::Y<float>::type::value == 1? 1 : -1]; +int a2[X<int>::Y<double>::type::value == 2? 1 : -1]; +int a3[X<int, int>::Y<double, double>::type::value == 3? 1 : -1]; |