namespace test0 {
template <typename T> struct Num {
T value_;
public:
Num(T value) : value_(value) {}
T get() const { return value_; }
template <typename U> struct Rep {
U count_;
Rep(U count) : count_(count) {}
friend Num operator*(const Num &a, const Rep &n) {
Num x = 0;
for (U count = n.count_; count; --count)
x += a;
return x;
}
};
friend Num operator+(const Num &a, const Num &b) {
return a.value_ + b.value_;
}
Num& operator+=(const Num& b) {
value_ += b.value_;
return *this;
}
class Representation {};
friend class Representation;
};
class A {
template <typename T> friend bool iszero(const A &a) throw();
};
template <class T> class B_iterator;
template <class T> class B {
friend class B_iterator<T>;
};
int calc1() {
Num<int> left = -1;
Num<int> right = 1;
Num<int> result = left + right;
return result.get();
}
int calc2() {
Num<int> x = 3;
Num<int>::Rep<char> n = (char) 10;
Num<int> result = x * n;
return result.get();
}
}
namespace test1 {
class A {
bool b; template <typename T> friend bool has(const A&);
};
template <typename T> bool has(const A &x) {
return x.b;
}
template <typename T> bool hasnot(const A &x) {
return x.b; }
}
namespace test2 {
class A {
bool b; template <typename T> friend class HasChecker;
};
template <typename T> class HasChecker {
bool check(A *a) {
return a->b;
}
};
template <typename T> class HasNotChecker {
bool check(A *a) {
return a->b; }
};
}
namespace test3 {
class Bool;
template <class T> class User;
template <class T> T transform(class Bool, T);
class Bool {
friend class User<bool>;
friend bool transform<>(Bool, bool);
bool value; };
template <class T> class User {
static T compute(Bool b) {
return b.value; }
};
template <class T> T transform(Bool b, T value) {
if (b.value) return value;
return value + 1;
}
template bool transform(Bool, bool);
template int transform(Bool, int);
template class User<bool>;
template class User<int>; }
namespace test4 {
template <class T> class A {
template <class T0> friend class B;
bool foo(const A<T> *) const;
};
template <class T> class B {
bool bar(const A<T> *a, const A<T> *b) {
return a->foo(b);
}
};
template class B<int>;
}
namespace test5 {
template <class T, class U=int> class A {};
template <class T> class B {
template <class X, class Y> friend class A;
};
template class B<int>;
template class A<int>;
}
namespace Dependent {
template<typename T, typename Traits> class X;
template<typename T, typename Traits>
X<T, Traits> operator+(const X<T, Traits>&, const T*);
template<typename T, typename Traits> class X {
typedef typename Traits::value_type value_type;
friend X operator+<>(const X&, const value_type*);
};
}
namespace test7 {
template <class T> class A { friend class B;
int x; };
class B {
int foo(A<int> &a) {
return a.x;
}
};
class C {
int foo(A<int> &a) {
return a.x; }
};
template <class T> class D {
friend class A; };
template class D<int>;
}
namespace test8 {
template <class N> class A {
static int x;
template <class T> friend void foo();
};
template class A<int>;
template <class T> void foo() {
A<int>::x = 0;
}
template void foo<int>();
}
namespace test9 {
template <class T> class A {
class B; class C;
int foo(B *b) {
return b->x;
}
int foo(C *c) {
return c->x; }
class B {
int x;
friend int A::foo(B*);
};
class C {
int x; };
};
template class A<int>; }
namespace test10 {
template <class T> class A;
template <class T> A<T> bar(const T*, const A<T>&);
template <class T> class A {
private:
void foo(); friend A bar<>(const T*, const A<T>&);
};
template <class T> A<T> bar(const T *l, const A<T> &r) {
A<T> l1;
l1.foo();
A<char> l2;
l2.foo();
return l1;
}
template A<int> bar<int>(const int *, const A<int> &); }
namespace test11 {
struct Foo {
template<class A>
struct IteratorImpl {
template<class T> friend class IteratorImpl;
};
};
template struct Foo::IteratorImpl<int>;
template struct Foo::IteratorImpl<long>;
}
namespace test12 {
template <typename T> class Foo;
template <typename T> Foo<T> foo(T* t){ return Foo<T>(t, true); }
template <typename T> class Foo {
public:
Foo(T*);
friend Foo<T> foo<T>(T*);
private:
Foo(T*, bool); };
int globalInt;
Foo<int> f = foo(&globalInt);
long globalLong;
template <> Foo<long> foo(long *t) {
Foo<int> s(&globalInt, false); return Foo<long>(t, true);
}
}
namespace test13 {
template <int N, template <int> class Temp>
class Role : public Temp<N> {
friend class Temp<N>;
int x;
};
template <int N> class Foo {
void foo(Role<N, test13::Foo> &role) {
(void) role.x;
}
};
template class Foo<0>;
}
namespace test14 {
template <class T> class B;
template <class T> class A {
friend void B<T>::foo();
static void foo(); };
template <class T> class B {
public:
void foo() { return A<long>::foo(); } };
template class B<int>; }
namespace test15 {
template <class T> class B;
template <class T> class A {
friend void B<T>::foo();
template <class U> friend void B<T>::bar(U);
static void foo(); };
template <class T> class B {
public:
void foo() { return A<long>::foo(); } };
template <> class B<float> {
public:
void foo() { return A<float>::foo(); }
template <class U> void bar(U u) {
(void) A<float>::foo();
}
};
template class B<int>; }
namespace PR10913 {
template<class T> class X;
template<class T> void f(X<T> *x) {
x->member = 0;
}
template<class U, class T> void f2(X<T> *x) {
x->member = 0; }
template<class T> class X {
friend void f<T>(X<T> *x);
friend void f2<T>(X<int> *x);
protected:
int member; };
template void f(X<int> *);
template void f2<int>(X<int> *);
template void f2<float>(X<int> *); }
namespace test16 {
template <class T> struct foo {}; template <class T> class A {
friend void foo<T>(); };
}
namespace test17 {
namespace ns {
template <class T> void foo() {} }
using ns::foo;
template <class T> struct A {
friend void foo<T>() {} };
}
namespace test18 {
namespace ns1 { template <class T> struct foo {}; } namespace ns2 { void foo() {} } using ns1::foo; using ns2::foo;
template <class T> class A {
friend void foo<T>() {} };
}