summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli-examples/features/driver.cxx25
-rw-r--r--cli-examples/features/options.cli7
-rw-r--r--cli/cli/pregenerated/cli/options.cxx50
-rw-r--r--cli/cli/runtime-source.cxx64
4 files changed, 138 insertions, 8 deletions
diff --git a/cli-examples/features/driver.cxx b/cli-examples/features/driver.cxx
index a6299b9..fc364a0 100644
--- a/cli-examples/features/driver.cxx
+++ b/cli-examples/features/driver.cxx
@@ -2,6 +2,7 @@
// author : Boris Kolpackov <boris@codesynthesis.com>
// license : MIT; see accompanying LICENSE file
+#include <utility> // pair
#include <iostream>
#include <iterator>
#include <algorithm>
@@ -45,13 +46,27 @@ main (int argc, char* argv[])
// --map | -m
//
- typedef map<std::string, bool> str_map;
- const str_map& m = o.map ();
- str_map::const_iterator i (m.find ("a"));
+ {
+ typedef map<string, bool> str_map;
+ const str_map& m = o.map ();
+ str_map::const_iterator i (m.find ("a"));
- if (i != m.end ())
- cerr << "value for the 'a' key: " << i->second << endl;
+ if (i != m.end ())
+ cerr << "value for the 'a' map key: " << i->second << endl;
+ }
+ // --multimap
+ //
+ {
+ typedef multimap<string, int> str_multimap;
+ const str_multimap& m = o.multimap ();
+
+ pair<str_multimap::const_iterator, str_multimap::const_iterator> r (
+ m.equal_range ("a"));
+
+ for (str_multimap::const_iterator i (r.first); i != r.second; ++i)
+ cerr << "value for the 'a' multimap key: " << i->second << endl;
+ }
}
catch (const cli::exception& e)
{
diff --git a/cli-examples/features/options.cli b/cli-examples/features/options.cli
index 4065830..d1e4b0c 100644
--- a/cli-examples/features/options.cli
+++ b/cli-examples/features/options.cli
@@ -30,10 +30,11 @@ namespace features
std::vector<int> --vector | -v;
std::set<int> --set | -s;
- // We can also use maps. In this case the option value is expected to have
- // two parts: the key and the value, separated by '='. For example: -m a=1
- // -m =true -m c= -m d (same as -m d=).
+ // We can also use maps and multimaps. In this case the option value is
+ // expected to have two parts: the key and the value, separated by '='.
+ // For example: -m a=1 -m =true -m c= -m d (same as -m d=).
//
std::map<std::string, bool> --map | -m;
+ std::multimap<std::string, int> --multimap;
};
}
diff --git a/cli/cli/pregenerated/cli/options.cxx b/cli/cli/pregenerated/cli/options.cxx
index 99aa50d..9f0be5f 100644
--- a/cli/cli/pregenerated/cli/options.cxx
+++ b/cli/cli/pregenerated/cli/options.cxx
@@ -676,6 +676,56 @@ namespace cli
}
};
+ template <typename K, typename V, typename C>
+ struct parser<std::multimap<K, V, C> >
+ {
+ static void
+ parse (std::multimap<K, V, C>& m, bool& xs, scanner& s)
+ {
+ const char* o (s.next ());
+
+ if (s.more ())
+ {
+ std::size_t pos (s.position ());
+ std::string ov (s.next ());
+ std::string::size_type p = ov.find ('=');
+
+ K k = K ();
+ V v = V ();
+ std::string kstr (ov, 0, p);
+ std::string vstr (ov, (p != std::string::npos ? p + 1 : ov.size ()));
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (o),
+ 0
+ };
+
+ bool dummy;
+ if (!kstr.empty ())
+ {
+ av[1] = const_cast<char*> (kstr.c_str ());
+ argv_scanner s (0, ac, av, false, pos);
+ parser<K>::parse (k, dummy, s);
+ }
+
+ if (!vstr.empty ())
+ {
+ av[1] = const_cast<char*> (vstr.c_str ());
+ argv_scanner s (0, ac, av, false, pos);
+ parser<V>::parse (v, dummy, s);
+ }
+
+ m.insert (typename std::multimap<K, V, C>::value_type (k, v));
+ }
+ else
+ throw missing_value (o);
+
+ xs = true;
+ }
+ };
+
template <typename X, typename T, T X::*M>
void
thunk (X& x, scanner& s)
diff --git a/cli/cli/runtime-source.cxx b/cli/cli/runtime-source.cxx
index 9620648..912027a 100644
--- a/cli/cli/runtime-source.cxx
+++ b/cli/cli/runtime-source.cxx
@@ -1216,6 +1216,70 @@ generate_runtime_source (context& ctx, bool complete)
os << "};";
+ // parser<std::multimap<K,V,C>>
+ //
+ os << "template <typename K, typename V, typename C>" << endl
+ << "struct parser<std::multimap<K, V, C> >"
+ << "{";
+
+ os << "static void" << endl
+ << "parse (std::multimap<K, V, C>& m, " << (sp ? "bool& xs, " : "") << "scanner& s)"
+ << "{"
+ << "const char* o (s.next ());"
+ << endl
+ << "if (s.more ())"
+ << "{"
+ << "std::size_t pos (s.position ());"
+ << "std::string ov (s.next ());"
+ << "std::string::size_type p = ov.find ('=');"
+ << endl
+ << "K k = K ();"
+ << "V v = V ();"
+ << "std::string kstr (ov, 0, p);"
+ << "std::string vstr (ov, (p != std::string::npos ? p + 1 : ov.size ()));"
+ << endl
+ << "int ac (2);"
+ << "char* av[] ="
+ << "{"
+ << "const_cast<char*> (o)," << endl
+ << "0"
+ << "};";
+ if (sp)
+ os << "bool dummy;";
+ os << "if (!kstr.empty ())"
+ << "{"
+ << "av[1] = const_cast<char*> (kstr.c_str ());"
+ << "argv_scanner s (0, ac, av, false, pos);"
+ << "parser<K>::parse (k, " << (sp ? "dummy, " : "") << "s);"
+ << "}"
+ << "if (!vstr.empty ())"
+ << "{"
+ << "av[1] = const_cast<char*> (vstr.c_str ());"
+ << "argv_scanner s (0, ac, av, false, pos);"
+ << "parser<V>::parse (v, " << (sp ? "dummy, " : "") << "s);"
+ << "}"
+ << "m.insert (typename std::multimap<K, V, C>::value_type (k, v));"
+ << "}"
+ << "else" << endl
+ << "throw missing_value (o);";
+ if (sp)
+ os << endl
+ << "xs = true;";
+ os << "}";
+
+ if (gen_merge)
+ os << "static void" << endl
+ << "merge (std::multimap<K, V, C>& b, const std::multimap<K, V, C>& a)"
+ << "{"
+ << "for (typename std::multimap<K, V, C>::const_iterator i (a.begin ()); " << endl
+ << "i != a.end (); " << endl
+ << "++i)" << endl
+ << "b.insert (typename std::multimap<K, V, C>::value_type (i->first," << endl
+ << "i->second));" << endl
+ << "}";
+
+ os << "};";
+
// Parser thunk.
//
os << "template <typename X, typename T, T X::*M>" << endl