Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
Actor Framework
Commits
776522ee
Commit
776522ee
authored
Sep 04, 2012
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
support for command line parsing (on_opt, on_vopt, rd_arg)
parent
ea2eafef
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
319 additions
and
2 deletions
+319
-2
cppa.files
cppa.files
+1
-0
cppa/detail/opt_impls.hpp
cppa/detail/opt_impls.hpp
+198
-0
cppa/opt.hpp
cppa/opt.hpp
+36
-2
src/opt.cpp
src/opt.cpp
+84
-0
No files found.
cppa.files
View file @
776522ee
...
@@ -271,3 +271,4 @@ examples/group_server.cpp
...
@@ -271,3 +271,4 @@ examples/group_server.cpp
examples/group_chat.cpp
examples/group_chat.cpp
cppa/opt.hpp
cppa/opt.hpp
src/opt.cpp
src/opt.cpp
cppa/detail/opt_impls.hpp
cppa/detail/opt_impls.hpp
0 → 100644
View file @
776522ee
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011, 2012 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation, either version 3 of the License *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#ifndef CPPA_OPT_IMPLS_HPP
#define CPPA_OPT_IMPLS_HPP
#include <sstream>
#include "cppa/on.hpp"
#include "cppa/option.hpp"
// this header contains implementation details for opt.hpp
namespace
cppa
{
namespace
detail
{
template
<
typename
T
>
struct
conv_arg_impl
{
typedef
option
<
T
>
result_type
;
static
inline
result_type
_
(
const
std
::
string
&
arg
)
{
std
::
istringstream
iss
(
arg
);
T
result
;
if
(
iss
>>
result
&&
iss
.
eof
())
{
return
result
;
}
return
{};
}
};
template
<
>
struct
conv_arg_impl
<
std
::
string
>
{
typedef
option
<
std
::
string
>
result_type
;
static
inline
result_type
_
(
const
std
::
string
&
arg
)
{
return
arg
;
}
};
template
<
bool
>
class
opt_rvalue_builder
;
template
<
typename
T
>
struct
rd_arg_storage
:
ref_counted
{
T
&
storage
;
bool
set
;
std
::
string
arg_name
;
rd_arg_storage
(
T
&
r
)
:
storage
(
r
),
set
(
false
)
{
}
};
template
<
typename
T
>
class
rd_arg_functor
{
template
<
bool
>
friend
class
opt_rvalue_builder
;
typedef
rd_arg_storage
<
T
>
storage_type
;
public:
rd_arg_functor
(
const
rd_arg_functor
&
)
=
default
;
rd_arg_functor
(
T
&
storage
)
:
m_storage
(
new
storage_type
(
storage
))
{
}
bool
operator
()(
const
std
::
string
&
arg
)
const
{
if
(
m_storage
->
set
)
{
std
::
cerr
<<
"*** error: "
<<
m_storage
->
arg_name
<<
" previously set to "
<<
m_storage
->
storage
<<
std
::
endl
;
}
else
{
auto
opt
=
conv_arg_impl
<
T
>::
_
(
arg
);
if
(
opt
)
{
m_storage
->
storage
=
*
opt
;
m_storage
->
set
=
true
;
return
true
;
}
else
{
std
::
cerr
<<
"*** error: cannot convert
\"
"
<<
arg
<<
"
\"
to "
<<
detail
::
demangle
(
typeid
(
T
).
name
())
<<
" [option:
\"
"
<<
m_storage
->
arg_name
<<
"
\"
]"
<<
std
::
endl
;
}
}
return
false
;
}
private:
intrusive_ptr
<
storage_type
>
m_storage
;
};
template
<
typename
T
>
struct
is_rd_arg
:
std
::
false_type
{
};
template
<
typename
T
>
struct
is_rd_arg
<
rd_arg_functor
<
T
>
>
:
std
::
true_type
{
};
template
<
bool
HasShortOpt
=
true
>
class
opt_rvalue_builder
{
public:
typedef
decltype
(
on
<
std
::
string
,
std
::
string
>
()
.
when
(
cppa
::
placeholders
::
_x1
.
in
(
std
::
vector
<
std
::
string
>
())))
left_type
;
typedef
decltype
(
on
(
std
::
function
<
option
<
std
::
string
>
(
const
std
::
string
&
)
>
()))
right_type
;
template
<
typename
Left
,
typename
Right
>
opt_rvalue_builder
(
char
sopt
,
std
::
string
lopt
,
Left
&&
lhs
,
Right
&&
rhs
)
:
m_short
(
sopt
),
m_long
(
std
::
move
(
lopt
))
,
m_left
(
std
::
forward
<
Left
>
(
lhs
)),
m_right
(
std
::
forward
<
Right
>
(
rhs
))
{
}
template
<
typename
Expr
>
auto
operator
>>
(
Expr
expr
)
->
decltype
((
*
(
static_cast
<
left_type
*>
(
nullptr
))
>>
expr
).
or_else
(
*
(
static_cast
<
right_type
*>
(
nullptr
))
>>
expr
))
const
{
return
(
m_left
>>
expr
).
or_else
(
m_right
>>
expr
);
}
private:
template
<
typename
T
>
inline
void
inject_arg_name
(
rd_arg_functor
<
T
>&
expr
)
{
expr
.
m_storage
->
arg_name
=
m_long
;
}
template
<
typename
T
>
inline
void
inject_arg_name
(
const
T
&
)
{
}
char
m_short
;
std
::
string
m_long
;
left_type
m_left
;
right_type
m_right
;
};
template
<
>
class
opt_rvalue_builder
<
false
>
{
public:
typedef
decltype
(
on
(
std
::
function
<
option
<
std
::
string
>
(
const
std
::
string
&
)
>
()))
sub_type
;
template
<
typename
SubType
>
opt_rvalue_builder
(
char
sopt
,
std
::
string
lopt
,
SubType
&&
sub
)
:
m_short
(
sopt
),
m_long
(
std
::
move
(
lopt
))
,
m_sub
(
std
::
forward
<
SubType
>
(
sub
))
{
}
template
<
typename
Expr
>
auto
operator
>>
(
Expr
expr
)
->
decltype
(
*
static_cast
<
sub_type
*>
(
nullptr
)
>>
expr
)
const
{
return
m_sub
>>
expr
;
}
private:
template
<
typename
T
>
inline
void
inject_arg_name
(
rd_arg_functor
<
T
>&
expr
)
{
expr
.
m_storage
->
arg_name
=
m_long
;
}
template
<
typename
T
>
inline
void
inject_arg_name
(
const
T
&
)
{
}
char
m_short
;
std
::
string
m_long
;
sub_type
m_sub
;
};
}
}
// namespace cppa::detail
#endif // CPPA_OPT_IMPLS_HPP
cppa/opt.hpp
View file @
776522ee
...
@@ -31,17 +31,51 @@
...
@@ -31,17 +31,51 @@
#ifndef CPPA_OPT_HPP
#ifndef CPPA_OPT_HPP
#define CPPA_OPT_HPP
#define CPPA_OPT_HPP
#include <map>
#include <string>
#include <iostream>
#include <functional>
#include "cppa/on.hpp"
#include "cppa/on.hpp"
#include "cppa/option.hpp"
#include "cppa/option.hpp"
#include "cppa/detail/demangle.hpp"
#include "cppa/detail/demangle.hpp"
#include "cppa/detail/opt_impls.hpp"
namespace
cppa
{
namespace
cppa
{
namespace
detail
{
template
<
typename
T
>
typename
detail
::
conv_arg_impl
<
T
>::
result_type
conv_arg
(
const
std
::
string
&
arg
)
{
return
detail
::
conv_arg_impl
<
T
>::
_
(
arg
);
}
template
<
typename
T
>
detail
::
rd_arg_functor
<
T
>
rd_arg
(
T
&
storage
)
{
return
{
storage
};
}
typedef
std
::
map
<
std
::
string
,
std
::
map
<
std
::
pair
<
char
,
std
::
string
>
,
std
::
string
>
>
options_description
;
detail
::
opt_rvalue_builder
<
true
>
on_opt
(
char
short_opt
,
std
::
string
long_opt
,
options_description
*
desc
=
nullptr
,
std
::
string
help_text
=
""
,
std
::
string
help_group
=
"general options"
);
decltype
(
on
<
std
::
string
>
()
.
when
(
cppa
::
placeholders
::
_x1
.
in
(
std
::
vector
<
std
::
string
>
())))
on_vopt
(
char
short_opt
,
std
::
string
long_opt
,
options_description
*
desc
=
nullptr
,
std
::
string
help_text
=
""
,
std
::
string
help_group
=
"general options"
);
std
::
function
<
void
()
>
print_desc
(
options_description
*
desc
,
std
::
ostream
&
out
=
std
::
cout
);
}
// namespace detail
std
::
function
<
void
()
>
print_desc_and_exit
(
options_description
*
desc
,
std
::
ostream
&
out
=
std
::
cout
,
int
exit_reason
=
0
);
}
// namespace cppa
}
// namespace cppa
...
...
src/opt.cpp
View file @
776522ee
...
@@ -28,5 +28,89 @@
...
@@ -28,5 +28,89 @@
\******************************************************************************/
\******************************************************************************/
#include <iomanip>
#include <algorithm>
#include "cppa/opt.hpp"
#include "cppa/opt.hpp"
using
namespace
std
;
using
cppa
::
placeholders
::
_x1
;
namespace
cppa
{
detail
::
opt_rvalue_builder
<
true
>
on_opt
(
char
short_opt
,
string
long_opt
,
options_description
*
desc
,
string
help_text
,
string
help_group
)
{
if
(
desc
)
{
(
*
desc
)[
help_group
].
insert
(
make_pair
(
make_pair
(
short_opt
,
long_opt
),
help_text
));
}
const
char
short_flag_arr
[]
=
{
'-'
,
short_opt
,
'\0'
};
const
char
*
lhs_str
=
short_flag_arr
;
string
prefix
=
"--"
;
prefix
+=
long_opt
;
prefix
+=
"="
;
function
<
option
<
string
>
(
const
string
&
)
>
kvp
=
[
prefix
](
const
string
&
input
)
->
option
<
string
>
{
if
(
equal
(
begin
(
prefix
),
end
(
prefix
),
begin
(
input
)))
{
return
input
.
substr
(
prefix
.
size
());
}
else
if
(
equal
(
begin
(
prefix
)
+
1
,
end
(
prefix
),
begin
(
input
)))
{
return
input
.
substr
(
prefix
.
size
()
-
1
);
}
return
{};
};
vector
<
string
>
opts
;
opts
.
push_back
(
lhs_str
);
opts
.
push_back
(
"--"
+
long_opt
);
opts
.
push_back
(
"-"
+
long_opt
);
return
{
short_opt
,
long_opt
,
on
<
string
,
string
>
().
when
(
_x1
.
in
(
opts
)),
on
(
kvp
)};
}
decltype
(
on
<
string
>
().
when
(
_x1
.
in
(
vector
<
string
>
())))
on_vopt
(
char
short_opt
,
string
long_opt
,
options_description
*
desc
,
string
help_text
,
string
help_group
)
{
if
(
desc
)
{
(
*
desc
)[
help_group
].
insert
(
make_pair
(
make_pair
(
short_opt
,
long_opt
),
help_text
));
}
const
char
short_flag_arr
[]
=
{
'-'
,
short_opt
,
'\0'
};
vector
<
string
>
opt_strs
=
{
short_flag_arr
};
opt_strs
.
push_back
(
"-"
+
long_opt
);
opt_strs
.
push_back
(
"--"
+
move
(
long_opt
));
return
on
<
string
>
().
when
(
_x1
.
in
(
move
(
opt_strs
)));
}
function
<
void
()
>
print_desc
(
options_description
*
desc
,
ostream
&
out
)
{
return
[
&
out
,
desc
]
{
if
(
!
desc
)
return
;
for
(
auto
&
opt_group
:
*
desc
)
{
out
<<
opt_group
.
first
<<
":
\n
"
;
for
(
auto
&
opt
:
opt_group
.
second
)
{
out
<<
" "
;
out
<<
std
::
setw
(
40
)
<<
left
;
ostringstream
tmp
;
auto
&
names
=
opt
.
first
;
if
(
names
.
first
!=
'\0'
)
{
tmp
<<
"-"
<<
names
.
first
<<
" <arg> | "
;
}
tmp
<<
"--"
<<
names
.
second
<<
" <arg>"
;
out
<<
tmp
.
str
()
<<
opt
.
second
<<
"
\n
"
;
}
out
<<
"
\n
"
;
}
};
}
function
<
void
()
>
print_desc_and_exit
(
options_description
*
desc
,
ostream
&
out
,
int
exit_reason
)
{
auto
fun
=
print_desc
(
desc
,
out
);
return
[
=
]
{
fun
();
exit
(
exit_reason
);
};
}
}
// namespace cppa
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment