text: //  boost::compressed_pair test program   
      
  //  (C) Copyright John Maddock 2000. 
  //  Use, modification and distribution are subject to the Boost Software License,
  //  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  //  http://www.boost.org/LICENSE_1_0.txt).
  
  
  // standalone test program for <boost/call_traits.hpp>
  // 18 Mar 2002:
  //    Changed some names to prevent conflicts with some new type_traits additions.
  // 03 Oct 2000:
  //    Enabled extra tests for VC6.
  
  #include <iostream>
  #include <iomanip>
  #include <algorithm>
  #include <typeinfo>
  #include <boost/call_traits.hpp>
  
  #include <libs/type_traits/test/test.hpp>
  #include <libs/type_traits/test/check_type.hpp>
  
  #ifdef BOOST_MSVC
  #pragma warning(disable:4181) // : warning C4181: qualifier applied to reference type; ignored
  #endif
  
  // a way prevent warnings for unused variables
  template<class T> inline void unused_variable(const T&) {}
  
  //
  // struct contained models a type that contains a type (for example std::pair)
  // arrays are contained by value, and have to be treated as a special case:
  //
  template <class T>
  struct contained
  {
     // define our typedefs first, arrays are stored by value
     // so value_type is not the same as result_type:
     typedef typename boost::call_traits<T>::param_type       param_type;
     typedef typename boost::call_traits<T>::reference        reference;
     typedef typename boost::call_traits<T>::const_reference  const_reference;
     typedef T                                                value_type;
     typedef typename boost::call_traits<T>::value_type       result_type;
  
     // stored value:
     value_type v_;
     
     // constructors:
     contained() {}
     contained(param_type p) : v_(p){}
     // return byval:
     result_type value()const { return v_; }
     // return by_ref:
     reference get() { return v_; }
     const_reference const_get()const { return v_; }
     // pass value:
     void call(param_type){}
  private:
     contained& operator=(const contained&);
  };
  
  #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  template <class T, std::size_t N>
  struct contained<T[N]>
  {
     typedef typename boost::call_traits<T[N]>::param_type       param_type;
     typedef typename boost::call_traits<T[N]>::reference        reference;
     typedef typename boost::call_traits<T[N]>::const_reference  const_reference;
     typedef T                                                   value_type[N];
     typedef typename boost::call_traits<T[N]>::value_type       result_type;
  
     value_type v_;
  
     contained(param_type p)
     {
        std::copy(p, p+N, v_);
     }
     // return byval:
     result_type value()const { return v_; }
     // return by_ref:
     reference get() { return v_; }
     const_reference const_get()const { return v_; }
     void call(param_type){}
  private:
     contained& operator=(const contained&);
  };
  #endif
  
  template <class T>
  contained<typename boost::call_traits<T>::value_type> test_wrap_type(const T& t)
  {
     typedef typename boost::call_traits<T>::value_type ct;
     return contained<ct>(t);
  }
  
  namespace test{
  
  template <class T1, class T2>
  std::pair<
     typename boost::call_traits<T1>::value_type,
     typename boost::call_traits<T2>::value_type>
        make_pair(const T1& t1, const T2& t2)
  {
     return std::pair<
        typename boost::call_traits<T1>::value_type,
        typename boost::call_traits<T2>::value_type>(t1, t2);
  }
  
  } // namespace test
  
  using namespace std;
  
  //
  // struct call_traits_checker:
  // verifies behaviour of contained example:
  //
  template <class T>
  struct call_traits_checker
  {
     typedef typename boost::call_traits<T>::param_type param_type;
     void operator()(param_type);
  };
  
  template <class T>
  void call_traits_checker<T>::operator()(param_type p)
  {
     T t(p);
     contained<T> c(t);
     cout << "checking contained<" << typeid(T).name() << ">..." << endl;
     BOOST_CHECK(t == c.value());
     BOOST_CHECK(t == c.get());
     BOOST_CHECK(t == c.const_get());
  #ifndef __ICL
     //cout << "typeof contained<" << typeid(T).name() << ">::v_ is:           " << typeid(&contained<T>::v_).name() << endl;
     cout << "typeof contained<" << typeid(T).name() << ">::value() is:      " << typeid(&contained<T>::value).name() << endl;
     cout << "typeof contained<" << typeid(T).name() << ">::get() is:        " << typeid(&contained<T>::get).name() << endl;
     cout << "typeof contained<" << typeid(T).name() << ">::const_get() is:  " << typeid(&contained<T>::const_get).name() << endl;
     cout << "typeof contained<" << typeid(T).name() << ">::call() is:       " << typeid(&contained<T>::call).name() << endl;
     cout << endl;
  #endif
  }
  
  #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  template <class T, std::size_t N>
  struct call_traits_checker<T[N]>
  {
     typedef typename boost::call_traits<T[N]>::param_type param_type;
     void operator()(param_type t)
     {
        contained<T[N]> c(t);
        cout << "checking contained<" << typeid(T[N]).name() << ">..." << endl;
        unsigned int i = 0;
        for(i = 0; i < N; ++i)
           BOOST_CHECK(t[i] == c.value()[i]);
        for(i = 0; i < N; ++i)
           BOOST_CHECK(t[i] == c.get()[i]);
        for(i = 0; i < N; ++i)
           BOOST_CHECK(t[i] == c.const_get()[i]);
  
        cout << "typeof contained<" << typeid(T[N]).name() << ">::v_ is:         " << typeid(&contained<T[N]>::v_).name() << endl;
        cout << "typeof contained<" << typeid(T[N]).name() << ">::value is:      " << typeid(&contained<T[N]>::value).name() << endl;
        cout << "typeof contained<" << typeid(T[N]).name() << ">::get is:        " << typeid(&contained<T[N]>::get).name() << endl;
        cout << "typeof contained<" << typeid(T[N]).name() << ">::const_get is:  " << typeid(&contained<T[N]>::const_get).name() << endl;
        cout << "typeof contained<" << typeid(T[N]).name() << ">::call is:       " << typeid(&contained<T[N]>::call).name() << endl;
        cout << endl;
     }
  };
  #endif
  
  //
  // check_wrap:
  template <class W, class U>
  void check_wrap(const W& w, const U& u)
  {
     cout << "checking " << typeid(W).name() << "..." << endl;
     BOOST_CHECK(w.value() == u);
  }
  
  //
  // check_make_pair:
  // verifies behaviour of "make_pair":
  //
  template <class T, class U, class V>
  void check_make_pair(T c, U u, V v)
  {
     cout << "checking std::pair<" << typeid(c.first).name() << ", " << typeid(c.second).name() << ">..." << endl;
     BOOST_CHECK(c.first == u);
     BOOST_CHECK(c.second == v);
     cout << endl;
  }
  
  
  struct comparible_UDT
  {
     int i_;
     comparible_UDT() : i_(2){}
     comparible_UDT(const comparible_UDT& other) : i_(other.i_){}
     comparible_UDT& operator=(const comparible_UDT& other)
     { 
        i_ = other.i_;
        return *this;
     }
     bool operator == (const comparible_UDT& v){ return v.i_ == i_; }
  };
  
  int main()
  {
     call_traits_checker<comparible_UDT> c1;
     comparible_UDT u;
     c1(u);
     call_traits_checker<int> c2;
     call_traits_checker<enum_UDT> c2b;
     int i = 2;
     c2(i);
     c2b(one);
     int* pi = &i;
     int a[2] = {1,2};
  #if defined(BOOST_MSVC6_MEMBER_TEMPLATES) && !defined(__ICL)
     call_traits_checker<int*> c3;
     c3(pi);
     call_traits_checker<int&> c4;
     c4(i);
     call_traits_checker<const int&> c5;
     c5(i);
  #if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__MWERKS__) && !defined(__SUNPRO_CC)
     call_traits_checker<int[2]> c6;
     c6(a);
  #endif
  #endif
  
     check_wrap(test_wrap_type(2), 2);
  #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__SUNPRO_CC)
     check_wrap(test_wrap_type(a), a);
     check_make_pair(test::make_pair(a, a), a, a);
  #endif
  
     // cv-qualifiers applied to reference types should have no effect
     // declare these here for later use with is_reference and remove_reference:
     typedef int& r_type;
     typedef const r_type cr_type;
  
     BOOST_CHECK_TYPE(comparible_UDT, boost::call_traits<comparible_UDT>::value_type);
     BOOST_CHECK_TYPE(comparible_UDT&, boost::call_traits<comparible_UDT>::reference);
     BOOST_CHECK_TYPE(const comparible_UDT&, boost::call_traits<comparible_UDT>::const_reference);
     BOOST_CHECK_TYPE(const comparible_UDT&, boost::call_traits<comparible_UDT>::param_type);
     BOOST_CHECK_TYPE(int, boost::call_traits<int>::value_type);
     BOOST_CHECK_TYPE(int&, boost::call_traits<int>::reference);
     BOOST_CHECK_TYPE(const int&, boost::call_traits<int>::const_reference);
     BOOST_CHECK_TYPE(const int, boost::call_traits<int>::param_type);
     BOOST_CHECK_TYPE(int*, boost::call_traits<int*>::value_type);
     BOOST_CHECK_TYPE(int*&, boost::call_traits<int*>::reference);
     BOOST_CHECK_TYPE(int*const&, boost::call_traits<int*>::const_reference);
     BOOST_CHECK_TYPE(int*const, boost::call_traits<int*>::param_type);
  #if defined(BOOST_MSVC6_MEMBER_TEMPLATES)
     BOOST_CHECK_TYPE(int&, boost::call_traits<int&>::value_type);
     BOOST_CHECK_TYPE(int&, boost::call_traits<int&>::reference);
     BOOST_CHECK_TYPE(const int&, boost::call_traits<int&>::const_reference);
     BOOST_CHECK_TYPE(int&, boost::call_traits<int&>::param_type);
  #if !(defined(__GNUC__) && ((__GNUC__ < 3) || (__GNUC__ == 3) && (__GNUC_MINOR__ < 1)))
     BOOST_CHECK_TYPE(int&, boost::call_traits<cr_type>::value_type);
     BOOST_CHECK_TYPE(int&, boost::call_traits<cr_type>::reference);
     BOOST_CHECK_TYPE(const int&, boost::call_traits<cr_type>::const_reference);
     BOOST_CHECK_TYPE(int&, boost::call_traits<cr_type>::param_type);
  #else
     std::cout << "Your compiler cannot instantiate call_traits<int&const>, skipping four tests (4 errors)" << std::endl;
  #endif
     BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::value_type);
     BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::reference);
     BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::const_reference);
     BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::param_type);
  #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
     BOOST_CHECK_TYPE(const int*, boost::call_traits<int[3]>::value_type);
     BOOST_CHECK_TYPE(int(&)[3], boost::call_traits<int[3]>::reference);
     BOOST_CHECK_TYPE(const int(&)[3], boost::call_traits<int[3]>::const_reference);
     BOOST_CHECK_TYPE(const int*const, boost::call_traits<int[3]>::param_type);
     BOOST_CHECK_TYPE(const int*, boost::call_traits<const int[3]>::value_type);
     BOOST_CHECK_TYPE(const int(&)[3], boost::call_traits<const int[3]>::reference);
     BOOST_CHECK_TYPE(const int(&)[3], boost::call_traits<const int[3]>::const_reference);
     BOOST_CHECK_TYPE(const int*const, boost::call_traits<const int[3]>::param_type);
     // test with abstract base class:
     BOOST_CHECK_TYPE(test_abc1, boost::call_traits<test_abc1>::value_type);
     BOOST_CHECK_TYPE(test_abc1&, boost::call_traits<test_abc1>::reference);
     BOOST_CHECK_TYPE(const test_abc1&, boost::call_traits<test_abc1>::const_reference);
     BOOST_CHECK_TYPE(const test_abc1&, boost::call_traits<test_abc1>::param_type);
  #else
     std::cout << "You're compiler does not support partial template specialiation, skipping 8 tests (8 errors)" << std::endl;
  #endif
  #else
     std::cout << "You're compiler does not support partial template specialiation, skipping 20 tests (20 errors)" << std::endl;
  #endif
     // test with an incomplete type:
     BOOST_CHECK_TYPE(incomplete_type, boost::call_traits<incomplete_type>::value_type);
     BOOST_CHECK_TYPE(incomplete_type&, boost::call_traits<incomplete_type>::reference);
     BOOST_CHECK_TYPE(const incomplete_type&, boost::call_traits<incomplete_type>::const_reference);
     BOOST_CHECK_TYPE(const incomplete_type&, boost::call_traits<incomplete_type>::param_type);
     // test enum:
     BOOST_CHECK_TYPE(enum_UDT, boost::call_traits<enum_UDT>::value_type);
     BOOST_CHECK_TYPE(enum_UDT&, boost::call_traits<enum_UDT>::reference);
     BOOST_CHECK_TYPE(const enum_UDT&, boost::call_traits<enum_UDT>::const_reference);
     BOOST_CHECK_TYPE(const enum_UDT, boost::call_traits<enum_UDT>::param_type);
     return 0;
  }
  
  //
  // define call_traits tests to check that the assertions in the docs do actually work
  // this is an compile-time only set of tests:
  //
  template <typename T, bool isarray = false>
  struct call_traits_test
  {
     typedef ::boost::call_traits<T> ct;
     typedef typename ct::param_type param_type;
     typedef typename ct::reference reference;
     typedef typename ct::const_reference const_reference;
     typedef typename ct::value_type value_type;
     static void assert_construct(param_type val);
  };
  
  template <typename T, bool isarray>
  void call_traits_test<T, isarray>::assert_construct(typename call_traits_test<T, isarray>::param_type val)
  {
     //
     // this is to check that the call_traits assertions are valid:
     T t(val);
     value_type v(t);
     reference r(t);
     const_reference cr(t);
     param_type p(t);
     value_type v2(v);
     value_type v3(r);
     value_type v4(p);
     reference r2(v);
     reference r3(r);
     const_reference cr2(v);
     const_reference cr3(r);
     const_reference cr4(cr);
     const_reference cr5(p);
     param_type p2(v);
     param_type p3(r);
     param_type p4(p);
     
     unused_variable(v2);
     unused_variable(v3);
     unused_variable(v4);
     unused_variable(r2);
     unused_variable(r3);
     unused_variable(cr2);
     unused_variable(cr3);
     unused_variable(cr4);
     unused_variable(cr5);
     unused_variable(p2);
     unused_variable(p3);
     unused_variable(p4);
  }
  #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  template <typename T>
  struct call_traits_test<T, true>
  {
     typedef ::boost::call_traits<T> ct;
     typedef typename ct::param_type param_type;
     typedef typename ct::reference reference;
     typedef typename ct::const_reference const_reference;
     typedef typename ct::value_type value_type;
     static void assert_construct(param_type val);
  };
  
  template <typename T>
  void call_traits_test<T, true>::assert_construct(typename boost::call_traits<T>::param_type val)
  {
     //
     // this is to check that the call_traits assertions are valid:
     T t;
     value_type v(t);
     value_type v5(val);
     reference r = t;
     const_reference cr = t;
     reference r2 = r;
     #ifndef __BORLANDC__
     // C++ Builder buglet:
     const_reference cr2 = r;
     #endif
     param_type p(t);
     value_type v2(v);
     const_reference cr3 = cr;
     value_type v3(r);
     value_type v4(p);
     param_type p2(v);
     param_type p3(r);
     param_type p4(p);
     
     unused_variable(v2);
     unused_variable(v3);
     unused_variable(v4);
     unused_variable(v5);
  #ifndef __BORLANDC__
     unused_variable(r2);
     unused_variable(cr2);
  #endif
     unused_variable(cr3);
     unused_variable(p2);
     unused_variable(p3);
     unused_variable(p4);
  }
  #endif //BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  //
  // now check call_traits assertions by instantiating call_traits_test:
  template struct call_traits_test<int>;
  template struct call_traits_test<const int>;
  template struct call_traits_test<int*>;
  #if defined(BOOST_MSVC6_MEMBER_TEMPLATES)
  template struct call_traits_test<int&>;
  template struct call_traits_test<const int&>;
  #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__SUNPRO_CC)
  template struct call_traits_test<int[2], true>;
  #endif
  #endif
  
  