template < typename T >
void ToStream ( std :: wostream & strm, const T & val ) ;
template < typename T >
std :: wstring ToString ( const T & val ) ;
template < typename T >
std :: wstring ToString ( const T & val )
{
std :: wostringstream strm ;
ToStream ( strm, val ) ;
return strm. str ( ) ;
}
template < typename T >
void ToStream ( std :: wostream & strm, const T & val )
{
strm << val ;
}
// T
//
struct AnyType
{
template < class T >
AnyType ( T )
{
}
} ;
//
// , (operator<<)
template < class Char >
boost :: type_traits :: no_type operator << ( std :: basic_ostream < Char > & , AnyType ) ;
// T ( T operator<<)?
template < class T, class Char >
class IsOutStreamable
{
static std :: basic_ostream < Char > & GetStrm ( ) ;
static const T & GetT ( ) ;
static boost :: type_traits :: no_type Impl ( boost :: type_traits :: no_type ) ;
static boost :: type_traits :: yes_type Impl ( ... ) ;
public :
static const bool value = sizeof ( Impl ( GetStrm ( ) << GetT ( ) ) ) == sizeof ( boost :: type_traits :: yes_type ) ;
} ;
// === T
template < typename T >
typename boost :: enable_if_c < IsOutStreamable < T, wchar_t > :: value , void > :: type
ToStream ( std :: wostream & strm, const T & val )
{
strm << val ;
}
// === std::pair
template < typename T, typename U >
void ToStream ( std :: wostream & strm, const std :: pair < T, U > & val )
{
strm << L '(' ;
ToStream ( strm, val. first ) ;
strm << L ", " ;
ToStream ( strm, val. second ) ;
strm << L ')' ;
}
// has_iterator ..
BOOST_MPL_HAS_XXX_TRAIT_DEF ( iterator ) ;
BOOST_MPL_HAS_XXX_TRAIT_DEF ( const_iterator ) ;
BOOST_MPL_HAS_XXX_TRAIT_DEF ( value_type ) ;
// " (STL container)"
// , ,
// iterator, const_iterator value_type, std::[w]string
template < typename T >
struct IsStdContainer
{
static const int value = boost :: mpl :: and_ <
has_iterator < T > ,
has_const_iterator < T > ,
has_value_type < T > ,
boost :: mpl :: not_ < boost :: is_same < T, std :: string > > ,
boost :: mpl :: not_ < boost :: is_same < T, std :: wstring > >
> :: value ;
} ;
// === STL ( , STL - . IsStdContainer )
template < typename T >
typename boost :: enable_if < IsStdContainer < T > , void > :: type
ToStream ( std :: wostream & strm, const T & val )
{
strm << L '[' << val. size ( ) << L "](" ;
if ( ! val. empty ( ) )
{
typename T :: const_iterator it = val. begin ( ) ;
ToStream ( strm, * it ++ ) ;
for ( ; it ! = val. end ( ) ; ++ it )
{
strm << L ", " ;
ToStream ( strm, * it ) ;
}
}
strm << L ')' ;
}
// === bool
void ToStream ( std :: wostream & strm, const bool & val )
{
strm << ( val ? L "true" : L "false" ) ;
}
// === std::string
void ToStream ( std :: wostream & strm, const std :: string & val ) ;
// === char*
void ToStream ( std :: wostream & strm, char * val ) ;
// === const char*
void ToStream ( std :: wostream & strm, const char * val ) ;
// === const char
void ToStream ( std :: wostream & strm, const char val ) ;
#define _VAR(var) L ## #var << L"<" << ToString(var) << L"> "
int i = 0 ;
int n = 10 ;
std :: cout << _VAR ( i ) << _VAR ( n ) ;
i < 0 > n < 10 >
std :: string s1 = "" ;
std :: string s2 = " " ;
std :: cout << _VAR ( s1 ) << _VAR ( s2 ) ;
s1 <> s2 < >
#define CHECK(expr) \
if ( ! ( expr ) ) \
{ \
throw #expr; \
} \
else \
( ( void ) 0 )
std :: vector < int > v = boost :: assign :: list_of ( 0 ) ( 1 ) ( 2 ) ( 3 ) ;
CHECK ( ToString ( v ) == L "[4](0, 1, 2, 3)" ) ;
std :: wcout << _VAR ( v ) << std :: endl ;
std :: map < int , int > m = boost :: assign :: map_list_of ( 0 , 1 ) ( 2 , 3 ) ( 4 , 5 ) ;
CHECK ( ToString ( m ) == L "[3]((0, 1), (2, 3), (4, 5))" ) ;
std :: wcout << _VAR ( m ) << std :: endl ;
< h4 > 3. std :: map . < / h4 >
. .
< code class = "cpp" >
std :: map < std :: wstring , std :: vector < int > > msv = boost :: assign :: list_of < std :: pair < std :: wstring , std :: vector < int > > >
( L "zero" , boost :: assign :: list_of ( 0 ) )
( L "one" , boost :: assign :: list_of ( 1 ) ( 2 ) )
( L "two" , boost :: assign :: list_of ( 2 ) ( 3 ) ( 4 ) )
;
CHECK ( ToString ( msv ) == L "[3]((one, [2](1, 2)), (two, [3](2, 3, 4)), (zero, [1](0)))" ) ;
std :: wcout << _VAR ( msv ) << std :: endl ;
enum RO4_ReplyType /// Reply type
{
RO4_RT_Mobile, ///< Replies go to mobile phone
RO4_RT_Email, ///< Replies go to email address
RO4_RT_MobileAndEmail ///< Replies go to mobile phone and to email address
} ;
RO4_ReplyType rt = RO4_RT_Email ;
CHECK ( RO4 :: Manip :: ToString ( rt ) == L "1" ) ;
/// Output operator for RO4_ReplyType
void ToStream ( std :: wostream & strm, const RO4_ReplyType & val )
{
#define STR(name) case name: strm << L## #name; break
switch ( val )
{
STR ( RO4_RT_Mobile ) ;
STR ( RO4_RT_Email ) ;
STR ( RO4_RT_MobileAndEmail ) ;
default :
strm << L "Unknown value of RO4_ReplyType<" << static_cast < int > ( val ) << L ">" ;
}
#undef STR
}
RO4_ReplyType rt = RO4_RT_Email ;
CHECK ( RO4 :: Manip :: ToString ( rt ) == L "RO4_RT_Email" ) ;
Source: https://habr.com/ru/post/81845/
All Articles