Commit fe55e3cb authored by Dominik Charousset's avatar Dominik Charousset

pattern matching improvements

this patch adds a new `match_split` function to split a string and match the
result, renames `on_vopt` to `on_opt0` and `on_opt` to `on_opt1` and adds
documentation to opt.hpp
parent c42dfa97
......@@ -115,6 +115,7 @@ set(LIBCPPA_SRC
src/ipv4_io_stream.cpp
src/local_actor.cpp
src/logging.cpp
src/match.cpp
src/message_header.cpp
src/middleman.cpp
src/object.cpp
......
......@@ -227,6 +227,7 @@ src/ipv4_acceptor.cpp
src/ipv4_io_stream.cpp
src/local_actor.cpp
src/logging.cpp
src/match.cpp
src/message_header.cpp
src/middleman.cpp
src/object.cpp
......
......@@ -59,7 +59,7 @@ struct conv_arg_impl<std::string> {
static inline result_type _(const std::string& arg) { return arg; }
};
template<bool> class opt_rvalue_builder;
template<bool> class opt1_rvalue_builder;
template<typename T>
struct rd_arg_storage : ref_counted {
......@@ -72,7 +72,7 @@ struct rd_arg_storage : ref_counted {
template<typename T>
class rd_arg_functor {
template<bool> friend class opt_rvalue_builder;
template<bool> friend class opt1_rvalue_builder;
typedef rd_arg_storage<T> storage_type;
......@@ -114,7 +114,7 @@ class rd_arg_functor {
template<typename T>
class add_arg_functor {
template<bool> friend class opt_rvalue_builder;
template<bool> friend class opt1_rvalue_builder;
public:
......@@ -153,8 +153,11 @@ struct is_rd_arg<rd_arg_functor<T> > : std::true_type { };
template<typename T>
struct is_rd_arg<add_arg_functor<T> > : std::true_type { };
typedef decltype(on<std::string>().when(cppa::placeholders::_x1.in(std::vector<std::string>())))
opt0_rvalue_builder;
template<bool HasShortOpt = true>
class opt_rvalue_builder {
class opt1_rvalue_builder {
public:
......@@ -166,7 +169,7 @@ class opt_rvalue_builder {
right_type;
template<typename Left, typename Right>
opt_rvalue_builder(char sopt, std::string lopt, Left&& lhs, Right&& rhs)
opt1_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)) { }
......@@ -196,7 +199,7 @@ class opt_rvalue_builder {
};
template<>
class opt_rvalue_builder<false> {
class opt1_rvalue_builder<false> {
public:
......@@ -204,7 +207,7 @@ class opt_rvalue_builder<false> {
sub_type;
template<typename SubType>
opt_rvalue_builder(char sopt, std::string lopt, SubType&& sub)
opt1_rvalue_builder(char sopt, std::string lopt, SubType&& sub)
: m_short(sopt), m_long(std::move(lopt))
, m_sub(std::forward<SubType>(sub)) { }
......
......@@ -329,6 +329,11 @@ detail::match_helper match(T&& what) {
return any_tuple::view(std::forward<T>(what));
}
/**
* @brief Splits @p str using @p delim and match the resulting strings.
*/
detail::match_helper match_split(const std::string& str, char delim, bool keep_empties = false);
/**
* @brief Starts a match expression that matches each element in
* range [first, last).
......
......@@ -44,46 +44,73 @@
namespace cppa {
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>
//option<T> conv_arg(const std::string& arg) {
// return detail::conv_arg_impl<T>::_(arg);
//}
/**
* @brief Right-hand side of a match expression for a program option
* reading an argument of type @p T.
*/
template<typename T>
detail::rd_arg_functor<T> rd_arg(T& storage) {
return {storage};
}
/**
* @brief Right-hand side of a match expression for a program option
* adding an argument of type @p T to @p storage.
*/
template<typename T>
detail::add_arg_functor<T> add_arg(std::vector<T>& storage) {
return {storage};
}
/**
* @brief Stores a help text along with the number of expected arguments.
*/
struct option_info {
std::string help_text;
size_t num_args;
};
/**
* @brief Stores a help text for program options with option groups.
*/
typedef std::map<std::string,std::map<std::pair<char,std::string>,option_info> >
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");
/**
* @brief Left-hand side of a match expression for a program option with
* one argument.
*/
detail::opt1_rvalue_builder<true> on_opt1(char short_opt,
std::string long_opt,
options_description* desc = nullptr,
std::string help_text = "",
std::string help_group = "general options");
/**
* @brief Left-hand side of a match expression for a program option with
* no argument.
*/
detail::opt0_rvalue_builder on_opt0(char short_opt,
std::string long_opt,
options_description* desc = nullptr,
std::string help_text = "",
std::string help_group = "general options");
/**
* @brief Returns a function that prints the help text of @p desc to @p out.
*/
std::function<void()> print_desc(options_description* desc,
std::ostream& out = std::cout);
/**
* @brief Returns a function that prints the help text of @p desc to @p out
* and then calls <tt>exit(exit_reason)</tt>.
*/
std::function<void()> print_desc_and_exit(options_description* desc,
std::ostream& out = std::cout,
int exit_reason = 0);
......
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \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/>. *
\******************************************************************************/
#include <vector>
#include <string>
#include <sstream>
#include "cppa/match.hpp"
using namespace std;
namespace cppa {
detail::match_helper match_split(const std::string& str, char delim, bool keep_empties) {
vector<string> result;
stringstream strs(str);
string tmp;
while (getline(strs, tmp, delim)) {
if (!tmp.empty() && !keep_empties) result.push_back(std::move(tmp));
}
return match(any_tuple::view(std::move(result)));
}
} // namespace cppa
......@@ -37,13 +37,13 @@ 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) {
detail::opt1_rvalue_builder<true> on_opt1(char short_opt,
string long_opt,
options_description* desc,
string help_text,
string help_group) {
if (desc) {
option_info oinf{help_text, 1};
option_info oinf{move(help_text), 1};
(*desc)[help_group].insert(make_pair(make_pair(short_opt, long_opt), move(oinf)));
}
const char short_flag_arr[] = {'-', short_opt, '\0' };
......@@ -68,7 +68,7 @@ detail::opt_rvalue_builder<true> on_opt(char short_opt,
}
decltype(on<string>().when(_x1.in(vector<string>())))
on_vopt(char short_opt,
on_opt0(char short_opt,
string long_opt,
options_description* desc,
string help_text,
......@@ -95,7 +95,7 @@ function<void()> print_desc(options_description* desc, ostream& out) {
out << opt_group.first << ":\n";
for (auto& opt : opt_group.second) {
out << " ";
out << std::setw(40) << left;
out << setw(40) << left;
ostringstream tmp;
auto& names = opt.first;
if (names.first != '\0') {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment