#include <list>
#include <map>
#include <vector>

#define MACRO(T)    f<T>()

class MyClass
{
 public:
   std::map<int, bool>             someData;
   std::map<int, std::list<bool> > otherData;
};

void foo()
{
   List<byte> bob = new List<byte>();
}

A<B>     foo;
A<B, C>  bar;
A<B *>   baz;
A<B<C> > bay;

void asd(void)
{
   A<B>     foo;
   A<B, C>  bar;
   A<B *>   baz;
   A<B<C> > bay;
   if (a < b && b > c)
   {
      a = b < c > 0;
   }
   if (a<bar()> c)
   {
   }
   a < up_lim() ? do_hi() : do_low;
   a[a < b > c] = d;
}

template<typename T> class MyClass
{
}

template<typename T>
class MyClass
{
}

template<typename A, typename B, typename C> class MyClass : myvar(0),
   myvar2(0)
{
}

template<typename A, typename B, typename C> class MyClass
   : myvar(0),
   myvar2(0)
{
}


static int max_value()
{
   return((std::numeric_limits<int>::max)());
}

template<class Config_>
priority_queue<Config_>::~priority_queue ()
{
}

template<class T>
T test(T a)
{
   return(a);
}

int main()
{
   int k, j;
   h   g<int>;

   k = test<int>(j);
   return(0);
}

template<typename T, template<typename, unsigned int, unsigned int> class ConcreteStorageClass>
class RotationMatrix
   : public StaticBaseMatrix<T, 3, 3, ConcreteStorageClass>
{
 public:
   RotationMatrix()
      : StaticBaseMatrix<T, 3, 3, ConcreteStorageClass>()
   {
      // do some initialization
   }

   void assign(const OtherClass<T, 3, 3>& other)
   {
      // do something
   }
};

int main()
{
   MyClass<double, 3, 3, MyStorage> foo;
}

template<typename CharT, int N, typename Traits>
inline std::basic_ostream<CharT, Traits>& FWStreamOut(std::basic_ostream<CharT, Traits>&os,
                                                      const W::S<CharT, N, Traits>&s)
{
   return(operator<<<CharT, N, Traits, char, std::char_traits<char> >(os, s));
}

struct foo
{
   type1<int&> bar;
};
struct foo
{
   type1<int const> bar;
};


template<int i> void f();
template<int i> void g()
{
   f<i - 1>();
   f<i>();
   f<i + 1>();
   f<bar()>();
}
void h()
{
   g<42>();
}

#include <vector>
std::vector<int> A(2);
std::vector<int> B;
std::vector<int> C(2);
std::vector<int> D;

template<class T> struct X
{
   template<class U> void operator()(U);
};

template<class T> class Y {
   template<class V> void f(V);
};

void                        (*foobar)(void) = NULL;
std::vector<void (*)(void)> functions;

#define MACRO(a)    a
template<typename = int> class X;
MACRO(void f(X<>& x));
void g(X<>& x);

#include <vector>
typedef std::vector<std::vector<int> >    Table; // OK
typedef std::vector<std::vector<bool> >   Flags; // Error

void func(List<B> =default_val1);
void func(List<List<B> > =default_val2);

BLAH<(3.14 >= 42)> blah;
bool               X = j<3> > 1;

void foo()
{
   A<(X > Y)> a;
   a = static_cast<List<B> >(ld);
}

template<int i> class X {   /* ... */
};
X < 1 > 2 > x1;             // Syntax error.
X<(1 > 2)> x2;              // Okay.

template<class T> class Y { /* ... */
};
Y<X<1> >        x3;         // Okay, same as "Y<X<1> > x3;".
Y<X<(6 >> 1)> > x4;


template<typename T>
int
myFunc1(typename T::Subtype val);

int
myFunc2(T::Subtype val);
