📄 tuple.h
字号:
// -*-c++-*-/*************************************************************************** tuple.h Classes for holding various types ------------------- begin : 8-MAR-2002 copyright : (C) 2002 by The RoboCup Soccer Server Maintenance Group. email : sserver-admin@lists.sourceforge.net ***************************************************************************//*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU LGPL as published by the Free Software * * Foundation; either version 2 of the License, or (at your option) any * * later version. * * * ***************************************************************************/#if 0#ifndef _TUPLE_H_#define _TUPLE_H_#include <exception>#include <string>#include "rcssexceptions.h" // needed for NullErrnamespace rcss{ namespace util { template< class H, class T > class TypeList { public: typedef H HeadType; typedef T TailType; }; class NullType {}; /* class NullErr : public std::exception { protected: std::string M_msg; public: NullErr ( const char* file, const int& line, const char* msg ) { std::ostrstream tmp; tmp << file << ": " << line << ": " << msg << std::ends; M_msg = tmp.str (); tmp.freeze ( false ); } ~NullErr () throw () { } const char* what () const throw () { return M_msg.c_str (); } };*/ // The generic Tuple class is great for an arbitory number of elements, // however, it usage results in may templates being instantiated. This // wouldn't be a problem except that ANSI C++ programs cannot rely on // a template instatiation depth greater than 17. The use of Tuple10 // has a much lower instatiation depth, so it comes in handy when the // depth is greater than 17, plus it's easier to use than the convoluted // syntax of the typelists which are needed for the genric Tuple template< class T > class Tuple; template< class H, class T > class Tuple< TypeList< H, T > > : public Tuple< T > { private: H* M_holder; public: // I coudn't get template specializations to work properly, // so I use dumby parameters instead. bool isTypeOf( H* ) const { return M_holder != 0; } template< class X > bool isTypeOf( X* x ) const { return Tuple< T >::isTypeOf( x ); } H& get( H* ) { if( M_holder == 0 ) throw NullErr( __FILE__, __LINE__, "Tried to access null element in Tuple" ); else return *M_holder; } template< class X > X& get( X* x ) { return Tuple< T >::get( x ); } const H& get( H* ) const { if( M_holder == 0 ) throw NullErr( __FILE__, __LINE__, "Tried to access null element in Tuple" ); else return *M_holder; } template< class X > const X& get( X* x ) const { return Tuple< T >::get( x ); } protected: void clear() { delete M_holder; M_holder = 0; } public: Tuple() : M_holder( 0 ) {} template< class X > Tuple( const X& x ) : Tuple< T >(), M_holder( 0 ) { setValue( x ); } Tuple( const Tuple< TypeList< H, T > >& tuple ) : Tuple< T >(), M_holder( 0 ) { setValue( tuple ); } ~Tuple() {} Tuple< TypeList< H, T > >& operator=( const Tuple< TypeList< H, T > >& tuple ) { return setValue( tuple ); } template< class X > bool isTypeOf() const { X* x = NULL; return isTypeOf( x ); } template< class X > X& get() { X* x = NULL; return get( x ); } template< class X > const X& get() const { X* x = NULL; return get( x ); } H& setValue( const H& h ) { clearAll(); M_holder = new H( h ); return *M_holder; } template< class X > X& setValue( const X& x ) { clear(); return Tuple< T >::setValue( x ); } Tuple< TypeList< H, T > >& setValue( const Tuple< TypeList< H, T > >& tuple ) { if( tuple.isTypeOf< H >() ) { // no need to clear. setValue( H ) will do that. setValue( tuple.get< H >() ); } else { clear(); Tuple< T >::setValue( (const Tuple< T >&)tuple ); } return *this; } void clearAll() { clear(); Tuple< T >::clearAll(); } template< class X > X& operator=( const X& x ) { return setValue( x ); } }; template< class H > class Tuple< TypeList< H, NullType > > { private: H* M_holder; public: bool isTypeOf( H* ) const { return M_holder != 0; } H& get( H* ) { if( M_holder == 0 ) throw NullErr( __FILE__, __LINE__, "Tried to access null element in Tuple" ); else return *M_holder; } const H& get( H* ) const { if( M_holder == 0 ) throw NullErr( __FILE__, __LINE__, "Tried to access null element in Tuple" ); else return *M_holder; } protected: void clear() { delete M_holder; M_holder = 0; } public: Tuple() : M_holder( 0 ) {} Tuple( const H& h ) : M_holder( 0 ) { setValue( h ); } Tuple( const Tuple< TypeList< H, NullType > >& tuple ) : M_holder( 0 ) { setValue( tuple ); } ~Tuple() {} Tuple< TypeList< H, NullType > >& operator=( const Tuple< TypeList< H, NullType > >& tuple ) { return setValue( tuple ); } template< class X > bool isTypeOf() const { X* x = NULL; return isTypeOf( x ); } template< class X > X& get() { X* x = NULL; return get( x ); } template< class X > const X& get() const { X* x = NULL; return get( x ); } H& setValue( const H& h ) { clear(); M_holder = new H( h ); return *M_holder; } Tuple< TypeList< H, NullType > >& setValue( const Tuple< TypeList< H, NullType > >& tuple ) { if( tuple.isTypeOf< H >() ) { // no need to clear. setValue( X ) will do that. setValue( tuple.get< H >() ); } else clear(); return *this; } void clearAll() { clear(); } template< class X > X& operator=( const X& x ) { return setValue( x ); } }; class NullType2 {}; class NullType3 {}; class NullType4 {}; class NullType5 {}; class NullType6 {}; class NullType7 {}; class NullType8 {}; class NullType9 {}; class NullType10 {}; template< typename T1 = NullType, typename T2 = NullType2, typename T3 = NullType3, typename T4 = NullType4, typename T5 = NullType5, typename T6 = NullType6, typename T7 = NullType7, typename T8 = NullType8, typename T9 = NullType9, typename T10 = NullType10 > class Tuple10 { private: T1* M_t1_holder; T2* M_t2_holder; T3* M_t3_holder; T4* M_t4_holder; T5* M_t5_holder; T6* M_t6_holder; T7* M_t7_holder; T8* M_t8_holder; T9* M_t9_holder; T10* M_t10_holder; public: bool isTypeOf( T1* ) const { return M_t1_holder != 0; } bool isTypeOf( T2* ) const { return M_t2_holder != 0; } bool isTypeOf( T3* ) const { return M_t3_holder != 0; } bool isTypeOf( T4* ) const { return M_t4_holder != 0; } bool isTypeOf( T5* ) const { return M_t5_holder != 0; } bool isTypeOf( T6* ) const { return M_t6_holder != 0; } bool isTypeOf( T7* ) const { return M_t7_holder != 0; } bool isTypeOf( T8* ) const { return M_t8_holder != 0; } bool isTypeOf( T9* ) const { return M_t9_holder != 0; } bool isTypeOf( T10* ) const { return M_t10_holder != 0; } T1& get( T1* ) { if( M_t1_holder == 0 ) throw NullErr( __FILE__, __LINE__, "Tried to access null element in Tuple" ); else return *M_t1_holder; } T2& get( T2* ) { if( M_t2_holder == 0 ) throw NullErr( __FILE__, __LINE__, "Tried to access null element in Tuple" ); else return *M_t2_holder; } T3& get( T3* ) { if( M_t3_holder == 0 ) throw NullErr( __FILE__, __LINE__, "Tried to access null element in Tuple" ); else return *M_t3_holder; } T4& get( T4* ) { if( M_t4_holder == 0 ) throw NullErr( __FILE__, __LINE__, "Tried to access null element in Tuple" ); else return *M_t4_holder; } T5& get( T5* ) { if( M_t5_holder == 0 ) throw NullErr( __FILE__, __LINE__, "Tried to access null element in Tuple" ); else return *M_t5_holder; } T6& get( T6* ) { if( M_t6_holder == 0 ) throw NullErr( __FILE__, __LINE__, "Tried to access null element in Tuple" ); else return *M_t6_holder; } T7& get( T7* ) { if( M_t7_holder == 0 ) throw NullErr( __FILE__, __LINE__, "Tried to access null element in Tuple" ); else return *M_t7_holder; } T8& get( T8* ) { if( M_t8_holder == 0 ) throw NullErr( __FILE__, __LINE__, "Tried to access null element in Tuple" ); else return *M_t8_holder; } T9& get( T9* ) { if( M_t9_holder == 0 ) throw NullErr( __FILE__, __LINE__, "Tried to access null element in Tuple" ); else return *M_t9_holder; } T10& get( T10* ) { if( M_t10_holder == 0 ) throw NullErr( __FILE__, __LINE__, "Tried to access null element in Tuple" ); else return *M_t10_holder; } const T1&
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -