mirror of
https://github.com/boostorg/test.git
synced 2026-01-30 08:22:12 +00:00
runtime.param examples added
[SVN r28150]
This commit is contained in:
290
example/cla/custom_parameter.cpp
Executable file
290
example/cla/custom_parameter.cpp
Executable file
@@ -0,0 +1,290 @@
|
||||
// (C) Copyright Gennadiy Rozental 2001-2004.
|
||||
// Distributed under 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)
|
||||
|
||||
// See http://www.boost.org/libs/test for the library home page.
|
||||
|
||||
// Boost.Runtime.Param
|
||||
#include <boost/test/utils/runtime/cla/named_parameter.hpp>
|
||||
#include <boost/test/utils/runtime/cla/parser.hpp>
|
||||
|
||||
namespace rt = boost::runtime;
|
||||
namespace cla = boost::runtime::cla;
|
||||
|
||||
// STL
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
|
||||
//_____________________________________________________________________//
|
||||
|
||||
struct Point : std::pair<int,int> {
|
||||
bool parse( rt::cstring& in ) {
|
||||
in.trim_left();
|
||||
|
||||
if( first_char( in ) != '(' )
|
||||
return false;
|
||||
|
||||
in.trim_left( 1 );
|
||||
rt::cstring::size_type pos = in.find( ")" );
|
||||
|
||||
if( pos == rt::cstring::npos )
|
||||
return false;
|
||||
|
||||
rt::cstring ss( in.begin(), pos );
|
||||
pos = ss.find( "," );
|
||||
|
||||
if( pos == rt::cstring::npos )
|
||||
return false;
|
||||
|
||||
rt::cstring f( ss.begin(), pos );
|
||||
rt::cstring s( ss.begin()+pos+1, ss.end() );
|
||||
|
||||
f.trim();
|
||||
s.trim();
|
||||
|
||||
try {
|
||||
first = boost::lexical_cast<int>( f );
|
||||
second = boost::lexical_cast<int>( s );
|
||||
}
|
||||
catch( boost::bad_lexical_cast const& ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
in.trim_left( ss.end()+1 );
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
std::ostream& operator<<( std::ostream& ostr, Point const& p )
|
||||
{
|
||||
ostr << '(' << p.first << ',' << p.second << ')';
|
||||
|
||||
return ostr;
|
||||
}
|
||||
|
||||
struct Segment : std::pair<Point,Point> {
|
||||
bool parse( rt::cstring& in ) {
|
||||
in.trim_left();
|
||||
|
||||
if( first_char( in ) != '[' )
|
||||
return false;
|
||||
|
||||
in.trim_left( 1 );
|
||||
|
||||
if( !first.parse( in ) )
|
||||
return false;
|
||||
|
||||
in.trim_left();
|
||||
|
||||
if( first_char( in ) != ',' )
|
||||
return false;
|
||||
|
||||
in.trim_left( 1 );
|
||||
|
||||
if( !second.parse( in ) )
|
||||
return false;
|
||||
|
||||
in.trim_left();
|
||||
|
||||
if( first_char( in ) != ']' )
|
||||
return false;
|
||||
|
||||
in.trim_left( 1 );
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
std::ostream& operator<<( std::ostream& ostr, Segment const& p )
|
||||
{
|
||||
ostr << '[' << p.first << ',' << p.second << ']';
|
||||
|
||||
return ostr;
|
||||
}
|
||||
|
||||
struct Circle : std::pair<Point,int> {
|
||||
bool parse( rt::cstring& in ) {
|
||||
in.trim_left();
|
||||
|
||||
if( first_char( in ) != '[' )
|
||||
return false;
|
||||
|
||||
in.trim_left( 1 );
|
||||
|
||||
if( !first.parse( in ) )
|
||||
return false;
|
||||
|
||||
in.trim_left();
|
||||
|
||||
if( first_char( in ) != ',' )
|
||||
return false;
|
||||
|
||||
in.trim_left( 1 );
|
||||
|
||||
rt::cstring::size_type pos = in.find( "]" );
|
||||
|
||||
if( pos == rt::cstring::npos )
|
||||
return false;
|
||||
|
||||
rt::cstring ss( in.begin(), pos );
|
||||
ss.trim();
|
||||
|
||||
try {
|
||||
second = boost::lexical_cast<int>( ss );
|
||||
}
|
||||
catch( boost::bad_lexical_cast const& ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
in.trim_left( pos+1 );
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
std::ostream& operator<<( std::ostream& ostr, Circle const& p )
|
||||
{
|
||||
ostr << '[' << p.first << ',' << p.second << ']';
|
||||
|
||||
return ostr;
|
||||
}
|
||||
|
||||
//_____________________________________________________________________//
|
||||
|
||||
template<typename T>
|
||||
class ShapeIdPolicy : public cla::identification_policy {
|
||||
rt::cstring m_name;
|
||||
rt::cstring m_usage_str;
|
||||
public:
|
||||
explicit ShapeIdPolicy( rt::cstring name )
|
||||
: cla::identification_policy( boost::rtti::type_id<ShapeIdPolicy<T> >() )
|
||||
, m_name( name ) {}
|
||||
|
||||
virtual bool responds_to( rt::cstring name ) const { return m_name == name; }
|
||||
virtual bool conflict_with( cla::identification_policy const& ) const { return false; }
|
||||
virtual rt::cstring id_2_report() const { return m_name; }
|
||||
virtual void usage_info( rt::format_stream& fs ) const { fs << m_name; }
|
||||
|
||||
virtual bool matching( cla::parameter const& p, cla::argv_traverser& tr, bool primary ) const
|
||||
{
|
||||
T s;
|
||||
|
||||
rt::cstring in = tr.input();
|
||||
return s.parse( in );
|
||||
}
|
||||
};
|
||||
|
||||
//_____________________________________________________________________//
|
||||
|
||||
template<typename T>
|
||||
class ShapeArgumentFactory : public cla::argument_factory {
|
||||
rt::cstring m_usage_str;
|
||||
public:
|
||||
explicit ShapeArgumentFactory( rt::cstring usage ) : m_usage_str( usage ) {}
|
||||
|
||||
// Argument factory interface
|
||||
virtual rt::argument_ptr produce_using( cla::parameter& p, cla::argv_traverser& tr )
|
||||
{
|
||||
T s;
|
||||
|
||||
rt::cstring in = tr.input();
|
||||
s.parse( in );
|
||||
tr.trim( in.begin() - tr.input().begin() );
|
||||
|
||||
if( !p.actual_argument() ) {
|
||||
rt::argument_ptr res;
|
||||
|
||||
rt::typed_argument<std::list<T> >* new_arg = new rt::typed_argument<std::list<T> >( p );
|
||||
|
||||
new_arg->p_value.value.push_back( s );
|
||||
res.reset( new_arg );
|
||||
|
||||
return res;
|
||||
}
|
||||
else {
|
||||
std::list<T>& arg_values = rt::arg_value<std::list<T> >( *p.actual_argument() );
|
||||
arg_values.push_back( s );
|
||||
|
||||
return p.actual_argument();
|
||||
}
|
||||
}
|
||||
virtual rt::argument_ptr produce_using( cla::parameter& p, cla::parser const& ) { return rt::argument_ptr(); }
|
||||
virtual void argument_usage_info( rt::format_stream& fs ) { fs << m_usage_str; }
|
||||
};
|
||||
|
||||
//_____________________________________________________________________//
|
||||
|
||||
struct SegmentParam : cla::parameter {
|
||||
SegmentParam()
|
||||
: cla::parameter( m_id_policy, m_arg_factory )
|
||||
, m_id_policy( "segment" )
|
||||
, m_arg_factory( ":((P1x,P1y), (P2x,P2y)) ... ((P1x,P1y), (P2x,P2y))" )
|
||||
{}
|
||||
|
||||
ShapeIdPolicy<Segment> m_id_policy;
|
||||
ShapeArgumentFactory<Segment> m_arg_factory;
|
||||
};
|
||||
|
||||
inline boost::shared_ptr<SegmentParam>
|
||||
segment_param() { return boost::shared_ptr<SegmentParam>( new SegmentParam ); }
|
||||
|
||||
//_____________________________________________________________________//
|
||||
|
||||
struct CircleParam : cla::parameter {
|
||||
CircleParam()
|
||||
: cla::parameter( m_id_policy, m_arg_factory )
|
||||
, m_id_policy( "circle" )
|
||||
, m_arg_factory( ":((P1x,P1y), R) ... ((P1x,P1y), R)" )
|
||||
{}
|
||||
|
||||
ShapeIdPolicy<Circle> m_id_policy;
|
||||
ShapeArgumentFactory<Circle> m_arg_factory;
|
||||
};
|
||||
|
||||
inline boost::shared_ptr<CircleParam>
|
||||
circle_param() { return boost::shared_ptr<CircleParam>( new CircleParam ); }
|
||||
|
||||
//_____________________________________________________________________//
|
||||
|
||||
int main() {
|
||||
char* argv[] = { "basic", "[(1,", "1)", ",", "(7,", "-1", ")]", "[(", "1,1)", ",7", "]", "[(3,", "1", ")", ",", "2]",
|
||||
"[", "(2,7", "),", "(5", ",1", ")]" };
|
||||
int argc = sizeof(argv)/sizeof(char*);
|
||||
|
||||
try {
|
||||
cla::parser P;
|
||||
|
||||
P << circle_param() - cla::optional
|
||||
<< segment_param() - cla::optional;
|
||||
|
||||
P.parse( argc, argv );
|
||||
|
||||
boost::optional<std::list<Segment> > segments;
|
||||
boost::optional<std::list<Circle> > circles;
|
||||
|
||||
P.get( "segment", segments );
|
||||
|
||||
if( segments ) {
|
||||
std::cout << "segments : ";
|
||||
std::copy( segments->begin(), segments->end(), std::ostream_iterator<Segment>( std::cout, "; " ) );
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
P.get( "circle", circles );
|
||||
|
||||
if( circles ) {
|
||||
std::cout << "circles : ";
|
||||
std::copy( circles->begin(), circles->end(), std::ostream_iterator<Circle>( std::cout, "; " ) );
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
catch( rt::logic_error const& ex ) {
|
||||
std::cout << "Logic error: " << ex.msg() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// EOF
|
||||
Reference in New Issue
Block a user