Members

Contents

The Type of An Element typeinfo<>

The type of an element can be obtained with ntuple<>'s typeinfo<> member class template.

enum what_t { eInt, eDouble, eChar };

what_t what( int ) { return eInt; }
what_t what( double ) { return eDouble; }
what_t what( char ) { return eChar; }

int main()
{
  typedef ntuple< int, double, char > tuple_t;
  
  tuple_t::typeinfo< 0 >::type _int( 3 );
  tuple_t::typeinfo< 1 >::type _double( 4.5 );
  tuple_t::typeinfo< 2 >::type _char( 'a' );
  
  CHECK( what( _int ) == eInt && _int == 3 );
  CHECK( what( _double ) == eDouble && _double == 4.5 );
  CHECK( what( _char ) == eChar && _char == 'a' );
  
  tuple_t tuple( _int, _double, _char );
  
  std::cout << tuple << std::endl;
  
  tuple_t::typeinfo< 0 >::remainder_type r = tuple.remainder();
  
  CHECK( r == ntuple_( _double, _char ) );
  
  return 0;
}

Test Result: gcc34 Passed, msvc80 Passed, msvc71 Passed

Output

(3,4.5,a)

Creating New Tuple Types

ntuple has two member class templates for creating new tuple types.

meta_apply<>

template < template < typename > class MF > struct meta_apply;

This member creates a tuple type by applying the meta-function MF to each element-type in turn.

In the test below widen is a meta-function that transforms char and short to int and float to double.

enum what_t { e_char, e_short, e_int, e_long, e_float, e_double };

#define JOIN( A, B ) A ## B
#define WHAT( Type ) \
what_t what( Type ) { return JOIN(e_, Type); }
WHAT( char )
WHAT( short )
WHAT( int )
WHAT( long )
WHAT( float )
WHAT( double )
#undef WHAT
#undef JOIN

template < typename T > struct widen
{
  typedef T type;
};
#define WIDEN( From, To ) \
template <> struct widen< From > { typedef To type; }
WIDEN( char, int );
WIDEN( short, int );
WIDEN( float, double );
#undef WIDEN

bool main()
{
  typedef ntuple< char, short, int, long, float, double > original_t;
  
  /* DOIT
  */
  typedef original_t::meta_apply< widen >::type wide_t;
  
  original_t original( 'a', 1, 2, 3, 1e20, 1e40 );
  wide_t wide( original );
  
  CHECK( original == wide );
  
  CHECK( what( original.at<0>() ) == e_char   && what( wide.at<0>() ) == e_int );
  CHECK( what( original.at<1>() ) == e_short  && what( wide.at<1>() ) == e_int );
  CHECK( what( original.at<2>() ) == e_int    && what( wide.at<2>() ) == e_int );
  CHECK( what( original.at<3>() ) == e_long   && what( wide.at<3>() ) == e_long );
  CHECK( what( original.at<4>() ) == e_float  && what( wide.at<4>() ) == e_double );
  CHECK( what( original.at<5>() ) == e_double && what( wide.at<5>() ) == e_double );
  
  std::cout << "original: " << original << "\twide: " << wide << std::endl;
  
  return true;
}

Test Result: gcc34 Passed, msvc80 Passed, msvc71 Passed

Output

original: (a,1,2,3,1e+020,1e+040) wide: (97,1,2,3,1e+020,1e+040)

meta_index_apply<>

template < template < typename, int > class IMF, int Offset = 0 > struct meta_index_apply;

As with meta_apply<>``_ above ``meta_index_apply<> transforms its tuple type into another tuple type, however meta_index_apply<> also passes the index of the element to its meta-function argument.

The following test uses constify, a meta-function that adds a const qualifier to the first N elements.

template < typename T, bool B > struct constify_helper
{
  typedef T type;
};
template < typename T > struct constify_helper< T, true >
{
  typedef T const type;
};

template < typename T, int Off > struct constify
{
  typedef typename constify_helper< T, (Off < 0) >::type type;
};

bool is_const( int &value )
{
  std::cout << value << " - is NOT constant\n";
  return false;
}
bool is_const( int const &value )
{
  std::cout << value << " - is constant\n";
  return true;
}

bool main()
{
  typedef ntuple< int, int, int, int, int > tuple_t;
  
  typedef tuple_t::meta_index_apply< constify, -2 >::type const2_t;
  
  const2_t const2( 0, 1, 2, 3, 4 );
  
  std::cout << std::boolalpha;
    
  CHECK( is_const( const2.at<0>() ) );
  CHECK( is_const( const2.at<1>() ) );
  CHECK( !is_const( const2.at<2>() ) );
  CHECK( !is_const( const2.at<3>() ) );
  CHECK( !is_const( const2.at<4>() ) );
  
  return true;
}

Test Result: gcc34 Passed, msvc80 Passed, msvc71 Passed

Output

0 - is constant
1 - is constant
2 - is NOT constant
3 - is NOT constant
4 - is NOT constant