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
This commit is contained in:
parent
5d80a30674
commit
d6a85c8dd4
@ -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
|
||||
|
476
gcc/testsuite/g++.dg/cpp0x/variadic-bind.C
Normal file
476
gcc/testsuite/g++.dg/cpp0x/variadic-bind.C
Normal file
@ -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;
|
||||
}
|
4
gcc/testsuite/g++.dg/cpp0x/variadic-ex1.C
Normal file
4
gcc/testsuite/g++.dg/cpp0x/variadic-ex1.C
Normal file
@ -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" }
|
9
gcc/testsuite/g++.dg/cpp0x/variadic-ex10.C
Normal file
9
gcc/testsuite/g++.dg/cpp0x/variadic-ex10.C
Normal file
@ -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 }
|
9
gcc/testsuite/g++.dg/cpp0x/variadic-ex11.C
Normal file
9
gcc/testsuite/g++.dg/cpp0x/variadic-ex11.C
Normal file
@ -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
|
||||
}
|
8
gcc/testsuite/g++.dg/cpp0x/variadic-ex12.C
Normal file
8
gcc/testsuite/g++.dg/cpp0x/variadic-ex12.C
Normal file
@ -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
|
||||
}
|
39
gcc/testsuite/g++.dg/cpp0x/variadic-ex13.C
Normal file
39
gcc/testsuite/g++.dg/cpp0x/variadic-ex13.C
Normal file
@ -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.
|
||||
}
|
23
gcc/testsuite/g++.dg/cpp0x/variadic-ex14.C
Normal file
23
gcc/testsuite/g++.dg/cpp0x/variadic-ex14.C
Normal file
@ -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
|
8
gcc/testsuite/g++.dg/cpp0x/variadic-ex2.C
Normal file
8
gcc/testsuite/g++.dg/cpp0x/variadic-ex2.C
Normal file
@ -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" }
|
9
gcc/testsuite/g++.dg/cpp0x/variadic-ex3.C
Normal file
9
gcc/testsuite/g++.dg/cpp0x/variadic-ex3.C
Normal file
@ -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" }
|
||||
}
|
12
gcc/testsuite/g++.dg/cpp0x/variadic-ex4.C
Normal file
12
gcc/testsuite/g++.dg/cpp0x/variadic-ex4.C
Normal file
@ -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
|
||||
}
|
7
gcc/testsuite/g++.dg/cpp0x/variadic-ex5.C
Normal file
7
gcc/testsuite/g++.dg/cpp0x/variadic-ex5.C
Normal file
@ -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
|
||||
}
|
13
gcc/testsuite/g++.dg/cpp0x/variadic-ex6.C
Normal file
13
gcc/testsuite/g++.dg/cpp0x/variadic-ex6.C
Normal file
@ -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
|
||||
}
|
13
gcc/testsuite/g++.dg/cpp0x/variadic-ex7.C
Normal file
13
gcc/testsuite/g++.dg/cpp0x/variadic-ex7.C
Normal file
@ -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
|
||||
}
|
18
gcc/testsuite/g++.dg/cpp0x/variadic-ex8.C
Normal file
18
gcc/testsuite/g++.dg/cpp0x/variadic-ex8.C
Normal file
@ -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");
|
10
gcc/testsuite/g++.dg/cpp0x/variadic-ex9.C
Normal file
10
gcc/testsuite/g++.dg/cpp0x/variadic-ex9.C
Normal file
@ -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
|
||||
}
|
96
gcc/testsuite/g++.dg/cpp0x/variadic-function.C
Normal file
96
gcc/testsuite/g++.dg/cpp0x/variadic-function.C
Normal file
@ -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;
|
||||
}
|
50
gcc/testsuite/g++.dg/cpp0x/variadic-mem_fn.C
Normal file
50
gcc/testsuite/g++.dg/cpp0x/variadic-mem_fn.C
Normal file
@ -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;
|
||||
}
|
294
gcc/testsuite/g++.dg/cpp0x/variadic-tuple.C
Normal file
294
gcc/testsuite/g++.dg/cpp0x/variadic-tuple.C
Normal file
@ -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);
|
||||
}
|
10
gcc/testsuite/g++.dg/cpp0x/variadic1.C
Normal file
10
gcc/testsuite/g++.dg/cpp0x/variadic1.C
Normal file
@ -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 { };
|
||||
|
22
gcc/testsuite/g++.dg/cpp0x/variadic10.C
Normal file
22
gcc/testsuite/g++.dg/cpp0x/variadic10.C
Normal file
@ -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;
|
18
gcc/testsuite/g++.dg/cpp0x/variadic11.C
Normal file
18
gcc/testsuite/g++.dg/cpp0x/variadic11.C
Normal file
@ -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];
|
42
gcc/testsuite/g++.dg/cpp0x/variadic12.C
Normal file
42
gcc/testsuite/g++.dg/cpp0x/variadic12.C
Normal file
@ -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];
|
19
gcc/testsuite/g++.dg/cpp0x/variadic13.C
Normal file
19
gcc/testsuite/g++.dg/cpp0x/variadic13.C
Normal file
@ -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];
|
21
gcc/testsuite/g++.dg/cpp0x/variadic14.C
Normal file
21
gcc/testsuite/g++.dg/cpp0x/variadic14.C
Normal file
@ -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];
|
21
gcc/testsuite/g++.dg/cpp0x/variadic15.C
Normal file
21
gcc/testsuite/g++.dg/cpp0x/variadic15.C
Normal file
@ -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];
|
21
gcc/testsuite/g++.dg/cpp0x/variadic16.C
Normal file
21
gcc/testsuite/g++.dg/cpp0x/variadic16.C
Normal file
@ -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];
|
21
gcc/testsuite/g++.dg/cpp0x/variadic17.C
Normal file
21
gcc/testsuite/g++.dg/cpp0x/variadic17.C
Normal file
@ -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];
|
47
gcc/testsuite/g++.dg/cpp0x/variadic18.C
Normal file
47
gcc/testsuite/g++.dg/cpp0x/variadic18.C
Normal file
@ -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];
|
||||
|
||||
|
19
gcc/testsuite/g++.dg/cpp0x/variadic19.C
Normal file
19
gcc/testsuite/g++.dg/cpp0x/variadic19.C
Normal file
@ -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];
|
17
gcc/testsuite/g++.dg/cpp0x/variadic2.C
Normal file
17
gcc/testsuite/g++.dg/cpp0x/variadic2.C
Normal file
@ -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>" }
|
||||
}
|
47
gcc/testsuite/g++.dg/cpp0x/variadic20.C
Normal file
47
gcc/testsuite/g++.dg/cpp0x/variadic20.C
Normal file
@ -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 }
|
7
gcc/testsuite/g++.dg/cpp0x/variadic21.C
Normal file
7
gcc/testsuite/g++.dg/cpp0x/variadic21.C
Normal file
@ -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;
|
21
gcc/testsuite/g++.dg/cpp0x/variadic22.C
Normal file
21
gcc/testsuite/g++.dg/cpp0x/variadic22.C
Normal file
@ -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];
|
25
gcc/testsuite/g++.dg/cpp0x/variadic23.C
Normal file
25
gcc/testsuite/g++.dg/cpp0x/variadic23.C
Normal file
@ -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];
|
6
gcc/testsuite/g++.dg/cpp0x/variadic24.C
Normal file
6
gcc/testsuite/g++.dg/cpp0x/variadic24.C
Normal file
@ -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;
|
16
gcc/testsuite/g++.dg/cpp0x/variadic25.C
Normal file
16
gcc/testsuite/g++.dg/cpp0x/variadic25.C
Normal file
@ -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];
|
24
gcc/testsuite/g++.dg/cpp0x/variadic26.C
Normal file
24
gcc/testsuite/g++.dg/cpp0x/variadic26.C
Normal file
@ -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];
|
22
gcc/testsuite/g++.dg/cpp0x/variadic27.C
Normal file
22
gcc/testsuite/g++.dg/cpp0x/variadic27.C
Normal file
@ -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];
|
25
gcc/testsuite/g++.dg/cpp0x/variadic28.C
Normal file
25
gcc/testsuite/g++.dg/cpp0x/variadic28.C
Normal file
@ -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];
|
35
gcc/testsuite/g++.dg/cpp0x/variadic29.C
Normal file
35
gcc/testsuite/g++.dg/cpp0x/variadic29.C
Normal file
@ -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];
|
10
gcc/testsuite/g++.dg/cpp0x/variadic3.C
Normal file
10
gcc/testsuite/g++.dg/cpp0x/variadic3.C
Normal file
@ -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;
|
||||
}
|
11
gcc/testsuite/g++.dg/cpp0x/variadic30.C
Normal file
11
gcc/testsuite/g++.dg/cpp0x/variadic30.C
Normal file
@ -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!");
|
||||
}
|
11
gcc/testsuite/g++.dg/cpp0x/variadic31.C
Normal file
11
gcc/testsuite/g++.dg/cpp0x/variadic31.C
Normal file
@ -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!");
|
||||
}
|
11
gcc/testsuite/g++.dg/cpp0x/variadic32.C
Normal file
11
gcc/testsuite/g++.dg/cpp0x/variadic32.C
Normal file
@ -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!");
|
||||
}
|
16
gcc/testsuite/g++.dg/cpp0x/variadic33.C
Normal file
16
gcc/testsuite/g++.dg/cpp0x/variadic33.C
Normal file
@ -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);
|
||||
}
|
11
gcc/testsuite/g++.dg/cpp0x/variadic34.C
Normal file
11
gcc/testsuite/g++.dg/cpp0x/variadic34.C
Normal file
@ -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');
|
||||
}
|
9
gcc/testsuite/g++.dg/cpp0x/variadic35.C
Normal file
9
gcc/testsuite/g++.dg/cpp0x/variadic35.C
Normal file
@ -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" }
|
||||
}
|
15
gcc/testsuite/g++.dg/cpp0x/variadic36.C
Normal file
15
gcc/testsuite/g++.dg/cpp0x/variadic36.C
Normal file
@ -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 }
|
10
gcc/testsuite/g++.dg/cpp0x/variadic37.C
Normal file
10
gcc/testsuite/g++.dg/cpp0x/variadic37.C
Normal file
@ -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];
|
6
gcc/testsuite/g++.dg/cpp0x/variadic38.C
Normal file
6
gcc/testsuite/g++.dg/cpp0x/variadic38.C
Normal file
@ -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" }
|
13
gcc/testsuite/g++.dg/cpp0x/variadic39.C
Normal file
13
gcc/testsuite/g++.dg/cpp0x/variadic39.C
Normal file
@ -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" }
|
15
gcc/testsuite/g++.dg/cpp0x/variadic4.C
Normal file
15
gcc/testsuite/g++.dg/cpp0x/variadic4.C
Normal file
@ -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" } }
|
3
gcc/testsuite/g++.dg/cpp0x/variadic40.C
Normal file
3
gcc/testsuite/g++.dg/cpp0x/variadic40.C
Normal file
@ -0,0 +1,3 @@
|
||||
// { dg-options "-std=gnu++0x" }
|
||||
template<typename... Values, typename T>
|
||||
struct backward_tuple {}; // { dg-error "end" }
|
3
gcc/testsuite/g++.dg/cpp0x/variadic41.C
Normal file
3
gcc/testsuite/g++.dg/cpp0x/variadic41.C
Normal file
@ -0,0 +1,3 @@
|
||||
// { dg-options "-std=gnu++0x" }
|
||||
template<typename... Args>
|
||||
void f(const Args&... args, int oops); // { dg-error "end" }
|
12
gcc/testsuite/g++.dg/cpp0x/variadic42.C
Normal file
12
gcc/testsuite/g++.dg/cpp0x/variadic42.C
Normal file
@ -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_" } }
|
8
gcc/testsuite/g++.dg/cpp0x/variadic43.C
Normal file
8
gcc/testsuite/g++.dg/cpp0x/variadic43.C
Normal file
@ -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;
|
||||
}
|
13
gcc/testsuite/g++.dg/cpp0x/variadic44.C
Normal file
13
gcc/testsuite/g++.dg/cpp0x/variadic44.C
Normal file
@ -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_"} }
|
10
gcc/testsuite/g++.dg/cpp0x/variadic45.C
Normal file
10
gcc/testsuite/g++.dg/cpp0x/variadic45.C
Normal file
@ -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);
|
||||
}
|
11
gcc/testsuite/g++.dg/cpp0x/variadic46.C
Normal file
11
gcc/testsuite/g++.dg/cpp0x/variadic46.C
Normal file
@ -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);
|
||||
}
|
18
gcc/testsuite/g++.dg/cpp0x/variadic47.C
Normal file
18
gcc/testsuite/g++.dg/cpp0x/variadic47.C
Normal file
@ -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);
|
||||
}
|
10
gcc/testsuite/g++.dg/cpp0x/variadic48.C
Normal file
10
gcc/testsuite/g++.dg/cpp0x/variadic48.C
Normal file
@ -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);
|
||||
}
|
9
gcc/testsuite/g++.dg/cpp0x/variadic49.C
Normal file
9
gcc/testsuite/g++.dg/cpp0x/variadic49.C
Normal file
@ -0,0 +1,9 @@
|
||||
// { dg-options "-std=gnu++0x" }
|
||||
int& f(...);
|
||||
|
||||
template<typename... Args>
|
||||
float& f(Args...);
|
||||
|
||||
float& g() {
|
||||
return f(17, 3.14159);
|
||||
}
|
38
gcc/testsuite/g++.dg/cpp0x/variadic5.C
Normal file
38
gcc/testsuite/g++.dg/cpp0x/variadic5.C
Normal file
@ -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];
|
9
gcc/testsuite/g++.dg/cpp0x/variadic50.C
Normal file
9
gcc/testsuite/g++.dg/cpp0x/variadic50.C
Normal file
@ -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);
|
||||
}
|
10
gcc/testsuite/g++.dg/cpp0x/variadic51.C
Normal file
10
gcc/testsuite/g++.dg/cpp0x/variadic51.C
Normal file
@ -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);
|
||||
}
|
7
gcc/testsuite/g++.dg/cpp0x/variadic52.C
Normal file
7
gcc/testsuite/g++.dg/cpp0x/variadic52.C
Normal file
@ -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;
|
17
gcc/testsuite/g++.dg/cpp0x/variadic53.C
Normal file
17
gcc/testsuite/g++.dg/cpp0x/variadic53.C
Normal file
@ -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)
|
||||
{
|
||||
}
|
12
gcc/testsuite/g++.dg/cpp0x/variadic54.C
Normal file
12
gcc/testsuite/g++.dg/cpp0x/variadic54.C
Normal file
@ -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()
|
||||
{
|
||||
}
|
12
gcc/testsuite/g++.dg/cpp0x/variadic55.C
Normal file
12
gcc/testsuite/g++.dg/cpp0x/variadic55.C
Normal file
@ -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&...)
|
||||
{
|
||||
}
|
19
gcc/testsuite/g++.dg/cpp0x/variadic56.C
Normal file
19
gcc/testsuite/g++.dg/cpp0x/variadic56.C
Normal file
@ -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; }
|
16
gcc/testsuite/g++.dg/cpp0x/variadic57.C
Normal file
16
gcc/testsuite/g++.dg/cpp0x/variadic57.C
Normal file
@ -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() { }
|
16
gcc/testsuite/g++.dg/cpp0x/variadic58.C
Normal file
16
gcc/testsuite/g++.dg/cpp0x/variadic58.C
Normal file
@ -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)...);
|
||||
}
|
4
gcc/testsuite/g++.dg/cpp0x/variadic59.C
Normal file
4
gcc/testsuite/g++.dg/cpp0x/variadic59.C
Normal file
@ -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 }
|
12
gcc/testsuite/g++.dg/cpp0x/variadic6.C
Normal file
12
gcc/testsuite/g++.dg/cpp0x/variadic6.C
Normal file
@ -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;
|
1
gcc/testsuite/g++.dg/cpp0x/variadic60.C
Normal file
1
gcc/testsuite/g++.dg/cpp0x/variadic60.C
Normal file
@ -0,0 +1 @@
|
||||
template<typename... Args> class tuple; // { dg-warning "variadic templates" }
|
2
gcc/testsuite/g++.dg/cpp0x/variadic61.C
Normal file
2
gcc/testsuite/g++.dg/cpp0x/variadic61.C
Normal file
@ -0,0 +1,2 @@
|
||||
// { dg-options "-pedantic" }
|
||||
template<typename... Args> class tuple; // { dg-warning "variadic templates" }
|
2
gcc/testsuite/g++.dg/cpp0x/variadic62.C
Normal file
2
gcc/testsuite/g++.dg/cpp0x/variadic62.C
Normal file
@ -0,0 +1,2 @@
|
||||
// { dg-options "-pedantic-errors" }
|
||||
template<typename... Args> class tuple; // { dg-error "variadic templates" }
|
2
gcc/testsuite/g++.dg/cpp0x/variadic63.C
Normal file
2
gcc/testsuite/g++.dg/cpp0x/variadic63.C
Normal file
@ -0,0 +1,2 @@
|
||||
// { dg-options "-std=gnu++0x -pedantic" }
|
||||
template<typename... Args> class tuple;
|
19
gcc/testsuite/g++.dg/cpp0x/variadic64.C
Normal file
19
gcc/testsuite/g++.dg/cpp0x/variadic64.C
Normal file
@ -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;
|
||||
};
|
8
gcc/testsuite/g++.dg/cpp0x/variadic65.C
Normal file
8
gcc/testsuite/g++.dg/cpp0x/variadic65.C
Normal file
@ -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" }
|
9
gcc/testsuite/g++.dg/cpp0x/variadic66.C
Normal file
9
gcc/testsuite/g++.dg/cpp0x/variadic66.C
Normal file
@ -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);
|
||||
}
|
24
gcc/testsuite/g++.dg/cpp0x/variadic67.C
Normal file
24
gcc/testsuite/g++.dg/cpp0x/variadic67.C
Normal file
@ -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];
|
23
gcc/testsuite/g++.dg/cpp0x/variadic68.C
Normal file
23
gcc/testsuite/g++.dg/cpp0x/variadic68.C
Normal file
@ -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;
|
||||
}
|
34
gcc/testsuite/g++.dg/cpp0x/variadic69.C
Normal file
34
gcc/testsuite/g++.dg/cpp0x/variadic69.C
Normal file
@ -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);
|
||||
}
|
33
gcc/testsuite/g++.dg/cpp0x/variadic7.C
Normal file
33
gcc/testsuite/g++.dg/cpp0x/variadic7.C
Normal file
@ -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];
|
22
gcc/testsuite/g++.dg/cpp0x/variadic70.C
Normal file
22
gcc/testsuite/g++.dg/cpp0x/variadic70.C
Normal file
@ -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;
|
||||
}
|
12
gcc/testsuite/g++.dg/cpp0x/variadic71.C
Normal file
12
gcc/testsuite/g++.dg/cpp0x/variadic71.C
Normal file
@ -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 }
|
21
gcc/testsuite/g++.dg/cpp0x/variadic72.C
Normal file
21
gcc/testsuite/g++.dg/cpp0x/variadic72.C
Normal file
@ -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);
|
||||
}
|
33
gcc/testsuite/g++.dg/cpp0x/variadic73.C
Normal file
33
gcc/testsuite/g++.dg/cpp0x/variadic73.C
Normal file
@ -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;
|
||||
}
|
26
gcc/testsuite/g++.dg/cpp0x/variadic74.C
Normal file
26
gcc/testsuite/g++.dg/cpp0x/variadic74.C
Normal file
@ -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;
|
33
gcc/testsuite/g++.dg/cpp0x/variadic75.C
Normal file
33
gcc/testsuite/g++.dg/cpp0x/variadic75.C
Normal file
@ -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");
|
23
gcc/testsuite/g++.dg/cpp0x/variadic8.C
Normal file
23
gcc/testsuite/g++.dg/cpp0x/variadic8.C
Normal file
@ -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];
|
38
gcc/testsuite/g++.dg/cpp0x/variadic9.C
Normal file
38
gcc/testsuite/g++.dg/cpp0x/variadic9.C
Normal file
@ -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];
|
Loading…
Reference in New Issue
Block a user