Listing 5: A test program that demonstrates various uses of variant_t

#include<iostream>
#include<sstream>
#include<vector>
#pragma hdrstop
#include <condefs.h>

#include "variant.h"

using namespace std ;

// test0() shows the basic construction and use of variant_t with
// various types.
void test0()
{
  variant_t _int ( 2 ) ;
  variant_t _dbl ( 3.14 ) ;
  variant_t _str ( string ( "This is a string" ) ) ;
  // IMPORTANT NOTE: The above statement COULD NOT have been
  //  variant_t _str ( "This is a string" ) ;
  // The expression "This is a string" is of type
  //  const char *, which is just a pointer.
  // The copy of a pointer is just another pointer of the
  // same value, not a new membory block with a copy of
  // the contents of the original block.
  // The value copied and stored in _str would be the
  // pointer value and not the character array contents.

  cout << "BEGIN test0" << endl ;
  cout << (int)   _int  << endl ;
  cout << (double)_dbl  << endl ;
  cout << (string)_str  << endl ;
  cout << "END test0"   << endl << endl ;
}

// test1() show how variant_t can be used as efficient
// return values. The internal data is not copied but shared
// among the various variant_t objects involved.
variant_t test1_aux()
{
  return variant_t ( string ( "This is a string" ) ) ;
}
void test1()
{
  cout << "BEGIN test1"       << endl ;
  cout << (string)test1_aux() << endl ;
  cout << "END test1"         << endl << endl ;
}

// test2() shows an invalid convertion throwing
// invalid_argument.
void test2()
{
  cout << "BEGIN test2" << endl ;
  try
  {
    variant_t _dbl(3.14);
    char* n = _dbl ; (n);
  }
  catch ( invalid_argument& x )
  {
    cout << "exception invalid_argument: " << x.what() << endl ;
  }
  cout << "END test2" << endl << endl ;
}

// test3() shows an array of variant_t
void test3()
{
  cout << "BEGIN test3" << endl ;
  variant_t Array [3];
  Array[0]=2;  // int
  Array[1]=3.14; // double
  Array[2]=string("This is a string");
  cout << (int)   Array[0] << endl ;
  cout << (double)Array[1] << endl ;
  cout << (string)Array[2] << endl ;
  cout << "END test3" << endl << endl ;
}

// test4() shows a vector<variant_t>
string print ( variant_t const& aVar )
{
  ostringstream ss ;
  if ( aVar.is_type<int>() )
  {
    ss << "int: " << (int)aVar ;
  }
  else if ( aVar.is_type<double>() )
  {
    ss << "double: " << (double)aVar ;
  }
  else if ( aVar.is_type<string>() )
  {
    ss << "string: " << (string)aVar ;
  }
  return ss.str();
}

void test4()
{
  cout << "BEGIN test4" << endl ;
  vector<variant_t> Vector ;
  Vector.push_back ( 2 ) ;
  Vector.push_back ( 3.14 ) ;
  Vector.push_back ( string("This is a string") ) ;
  std::transform ( Vector.begin() ,
                   Vector.end  () ,
                   ostream_iterator<string> ( cout , "\n" ) ,
                   print
                 ) ;
  cout << "END test4" << endl << endl ;
}

int main()
{
  test0() ;
  test1() ;
  test2() ;
  test3() ;
  test4() ;

  return 0 ;
}

/*
OUTPUT:

BEGIN test0
2
3.14
This is a string
END test0

BEGIN test1
This is a string
END test1

BEGIN test2
exception invalid_argument: char * is not a valid type
END test2

BEGIN test3
2
3.14
This is a string
END test3

BEGIN test4
int: 2
double: 3.14
string: This is a string
END test4
*/