/
parser.hpp
135 lines (115 loc) · 5.84 KB
/
parser.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#ifndef LBGFRQVUVNDGCURGOHUTPFAJDBUFCDTXYCHJNKPJKVQPUHSVSDAWQVLNCDWICKFLCGPLYKNSN
#define LBGFRQVUVNDGCURGOHUTPFAJDBUFCDTXYCHJNKPJKVQPUHSVSDAWQVLNCDWICKFLCGPLYKNSN
#include <sstream>
#include <string>
#include <cstddef>
#include <functional>
#include <algorithm>
#include <iterator>
#include <vector>
template< typename T > struct tag
{
typedef T value_type;
};
template< unsigned long N >
struct integer
{
static const unsigned long value = N;
};
template< typename ... Types >
auto option( Types ... args )
{
return [=]( auto invoker ) { return invoker( args ... ); };
}
template< typename T, typename Triggered_Action, typename Silent_Action >
auto make_option( std::string token_, Triggered_Action triggered_action_, Silent_Action silent_action_ )
{
return option( token_, triggered_action_, silent_action_, tag<T>{} );
}
template< typename T, unsigned long N, typename Triggered_Action, typename Silent_Action >
auto make_option( std::string token_, char delimiter_, Triggered_Action triggered_action_, Silent_Action silent_action_ )
{
return option( token_, delimiter_, triggered_action_, silent_action_, tag<T>{}, integer<N>{} );
}
template< typename T, typename Triggered_Action >
auto make_option( std::string token_, Triggered_Action triggered_action_ )
{
return make_option<T>( token_, triggered_action_, [](){} );
}
template< typename T, unsigned long N, typename Triggered_Action >
auto make_option( std::string token_, char delimiter_, Triggered_Action triggered_action_ )
{
return make_option<T, N>( token_, delimiter_, triggered_action_, [](){} );
}
template< typename Arg, typename ... Args >
struct overloader : Arg, overloader<Args...>
{
overloader( Arg arg_, Args ... args_ ) : Arg(arg_), overloader<Args...>( args_... ) {}
};
template< typename Arg >
struct overloader<Arg> : Arg
{
overloader( Arg arg_ ) : Arg(arg_){}
};
template< typename ... Args >
auto make_parser( Args ... args_ )
{
return overloader<Args...>{ args_... };
}
template< typename Option, typename ... Options >
auto parse( int argc_, char** argv_, Option option_, Options ... options_ )
{
auto parser = make_parser( [=]( std::string token_, char delimiter_, auto triggered_action_, auto silent_action_, auto tag_, auto integer_ )
{
for ( int index = 1; index != argc_; ++index )
if ( 0 == strcmp( argv_[index], token_.c_str() ) )
{
if ( index+1 == argc_ ) return 1;
std::string str_{ argv_[index+1] };
if ( integer_.value-1 != std::count( str_.begin(), str_.end(), delimiter_ ) ) return 1;
for( auto& ch : str_ ) ch = ( ch == delimiter_ ) ? ' ' : ch;
std::istringstream iss{ str_ };
typedef typename decltype(tag_)::value_type value_type;
std::vector<value_type> vals( integer_.value, 0.0 );
std::copy( std::istream_iterator<value_type>( iss ), std::istream_iterator<value_type>(), vals.begin() );
if ( iss.bad() ) return 1;
triggered_action_( vals.data() );
return 0;
}
silent_action_();
return 0;
},
[=]( std::string token_, auto triggered_action_, auto silent_action_, auto tag_ )
{
for ( int index = 1; index != argc_; ++index )
if ( 0 == strcmp( argv_[index], token_.c_str() ) )
{
typedef typename decltype(tag_)::value_type value_type;
if ( index+1 == argc_ ) return 1;
value_type val;
std::istringstream iss{ std::string{ argv_[index+1] } };
iss >> val;
if ( iss.bad() ) return 1;
triggered_action_( val );
return 0;
}
silent_action_();
return 0;
},
[=]( std::string token_, auto triggered_action_, auto silent_action_, tag<void> )
{
for ( int index = 1; index != argc_; ++index )
{
if ( 0 == strcmp( argv_[index], token_.c_str() ) )
{
triggered_action_();
return 0;
}
}
silent_action_();
return 0;
}
);
return option( option_(parser), options_(parser)... );
}
#endif//LBGFRQVUVNDGCURGOHUTPFAJDBUFCDTXYCHJNKPJKVQPUHSVSDAWQVLNCDWICKFLCGPLYKNSN