Does boost have a datatype for set operations that is simpler than the STL?
See Boost Range Set algorithms. They still expect an output iterator though.
Does Boost or STL provide a functionlity similar to QString?
Seems like you want boost.format
A boost or stl api for hashing a strings array in the form of string= array-index
First of all, have you benchmarked that the current implementation is particular slow? You should always benchmark before trying to optimize.
Anyway, it would seem that boost::bimap<>
is just what you asked for. Then you simply replace the array with a boost::bimap
, and make up your own indices on the fly.
Boost vectors versus STL vectors
You should only use ublas::vector if you want to do linear algebra operations, such as matrix vector multiplication etc.
They do not provide the same functionality nor the same interface as std::vector.
In terms of run-time efficiency, there is nothing, that I know of, that beats std::vector.
Min/Max dyadic operators
There's the ISO working group 21 who decide what goes into the ISO C++ standard and what doesn't.
And here's the process of submitting a proposal to WG21.
It begins with participating in the mailings of the working group and getting on the agenda of an upcoming meeting to discuss your idea. It's actually possible, but it takes a lot of effort.
Parsing struct with enum fields and STL containers easily using Boost Spirit/Fusion
So, making some assumptions as your examples don't make the meaning very clear. But here goes:
Going with a random enum:
enum class Level { One, Two, Three, LEVEL };
Sidenote: the
std::set<>
might need to be a sequential container, because usuallygroupby
operations are not commutative (the order matters). I don't know about your domain, of course,
Adapting:
BOOST_FUSION_ADAPT_STRUCT(ComputeTask, level, aggregator, dataname, groupby)
BOOST_FUSION_ADAPT_STRUCT(Schedule, tasks)
Note that I subtly put the adapted fields in the grammar order. That helps a lot down the road.
The simplest grammar that comes to mind:
template <typename It>
struct Parser : qi::grammar<It, Schedule()> {
Parser() : Parser::base_type(_start) {
using namespace qi;
_any_word = lexeme [ +char_("a-zA-Z0-9-_./") ];
_operation = _any_word; // TODO
_group_field = _any_word; // TODO
_dataname = _any_word; // TODO
_level = no_case [ _level_sym ];
_groupby = '(' >> -(_group_field % ',') >> ')';
_task = _level >> _operation >> _dataname >> "on" >> _groupby;
_entry = _level >> ':' >> _task;
_schedule = _entry % eol;
_start = skip(blank) [ _schedule ];
BOOST_SPIRIT_DEBUG_NODES((_start)(_schedule)(_task)(_groupby)(_level)(_operation)(_dataname)(_group_field))
}
private:
struct level_sym : qi::symbols<char, Level> {
level_sym() { this->add
("one", Level::One)
("two", Level::Two)
("three", Level::Three)
("level", Level::LEVEL);
}
} _level_sym;
// lexemes
qi::rule<It, std::string()> _any_word;
qi::rule<It, std::string()> _operation, _dataname, _group_field; // TODO
qi::rule<It, Level()> _level;
using Skipper = qi::blank_type;
using Table = decltype(Schedule::tasks);
using Entry = std::pair<Level, ComputeTask>;
qi::rule<It, std::set<std::string>(), Skipper> _groupby;
qi::rule<It, ComputeTask(), Skipper> _task;
qi::rule<It, Entry(), Skipper> _entry;
qi::rule<It, Table(), Skipper> _schedule;
qi::rule<It, Schedule()> _start;
};
I changed the input to have unique keys for Level
in the schedule, otherwise only one entry would actually result.
int main() {
Parser<std::string::const_iterator> const parser;
for (std::string const input : { R"(ONE: level operation name on(data1, data2, data3)
TWO: level operation name on()
THREE: level operation name on(data1, data2))" })
{
auto f = begin(input), l = end(input);
Schedule s;
if (parse(f, l, parser, s)) {
std::cout << "Parsed\n";
for (auto& [level, task] : s.tasks) {
std::cout << level << ": " << task << "\n";
}
} else {
std::cout << "Failed\n";
}
if (f != l) {
std::cout << "Remaining unparsed input: " << std::quoted(std::string(f,l)) << "\n";
}
}
}
Prints
Parsed
One: LEVEL operation name on (data1, data2, data3)
Two: LEVEL operation name on ()
Three: LEVEL operation name on (data1, data2)
And, additonally with BOOST_SPIRIT_DEBUG
defined:
<_start>
<try>ONE: level operation</try>
<_schedule>
<try>ONE: level operation</try>
<_level>
<try>ONE: level operation</try>
<success>: level operation na</success>
<attributes>[One]</attributes>
</_level>
<_task>
<try> level operation nam</try>
<_level>
<try>level operation name</try>
<success> operation name on(d</success>
<attributes>[LEVEL]</attributes>
</_level>
<_operation>
<try>operation name on(da</try>
<success> name on(data1, data</success>
<attributes>[[o, p, e, r, a, t, i, o, n]]</attributes>
</_operation>
<_dataname>
<try>name on(data1, data2</try>
<success> on(data1, data2, da</success>
<attributes>[[n, a, m, e]]</attributes>
</_dataname>
<_groupby>
<try>(data1, data2, data3</try>
<_group_field>
<try>data1, data2, data3)</try>
<success>, data2, data3)\nTWO:</success>
<attributes>[[d, a, t, a, 1]]</attributes>
</_group_field>
<_group_field>
<try>data2, data3)\nTWO: l</try>
<success>, data3)\nTWO: level </success>
<attributes>[[d, a, t, a, 2]]</attributes>
</_group_field>
<_group_field>
<try>data3)\nTWO: level op</try>
<success>)\nTWO: level operati</success>
<attributes>[[d, a, t, a, 3]]</attributes>
</_group_field>
<success>\nTWO: level operatio</success>
<attributes>[[[d, a, t, a, 1], [d, a, t, a, 2], [d, a, t, a, 3]]]</attributes>
</_groupby>
<success>\nTWO: level operatio</success>
<attributes>[[LEVEL, [o, p, e, r, a, t, i, o, n], [n, a, m, e], [[d, a, t, a, 1], [d, a, t, a, 2], [d, a, t, a, 3]]]]</attributes>
</_task>
<_level>
<try>TWO: level operation</try>
<success>: level operation na</success>
<attributes>[Two]</attributes>
</_level>
<_task>
<try> level operation nam</try>
<_level>
<try>level operation name</try>
<success> operation name on()</success>
<attributes>[LEVEL]</attributes>
</_level>
<_operation>
<try>operation name on()\n</try>
<success> name on()\nTHREE: le</success>
<attributes>[[o, p, e, r, a, t, i, o, n]]</attributes>
</_operation>
<_dataname>
<try>name on()\nTHREE: lev</try>
<success> on()\nTHREE: level o</success>
<attributes>[[n, a, m, e]]</attributes>
</_dataname>
<_groupby>
<try>()\nTHREE: level oper</try>
<_group_field>
<try>)\nTHREE: level opera</try>
<fail/>
</_group_field>
<success>\nTHREE: level operat</success>
<attributes>[[]]</attributes>
</_groupby>
<success>\nTHREE: level operat</success>
<attributes>[[LEVEL, [o, p, e, r, a, t, i, o, n], [n, a, m, e], []]]</attributes>
</_task>
<_level>
<try>THREE: level operati</try>
<success>: level operation na</success>
<attributes>[Three]</attributes>
</_level>
<_task>
<try> level operation nam</try>
<_level>
<try>level operation name</try>
<success> operation name on(d</success>
<attributes>[LEVEL]</attributes>
</_level>
<_operation>
<try>operation name on(da</try>
<success> name on(data1, data</success>
<attributes>[[o, p, e, r, a, t, i, o, n]]</attributes>
</_operation>
<_dataname>
<try>name on(data1, data2</try>
<success> on(data1, data2)</success>
<attributes>[[n, a, m, e]]</attributes>
</_dataname>
<_groupby>
<try>(data1, data2)</try>
<_group_field>
<try>data1, data2)</try>
<success>, data2)</success>
<attributes>[[d, a, t, a, 1]]</attributes>
</_group_field>
<_group_field>
<try>data2)</try>
<success>)</success>
<attributes>[[d, a, t, a, 2]]</attributes>
</_group_field>
<success></success>
<attributes>[[[d, a, t, a, 1], [d, a, t, a, 2]]]</attributes>
</_groupby>
<success></success>
<attributes>[[LEVEL, [o, p, e, r, a, t, i, o, n], [n, a, m, e], [[d, a, t, a, 1], [d, a, t, a, 2]]]]</attributes>
</_task>
<success></success>
<attributes>[[[One, [LEVEL, [o, p, e, r, a, t, i, o, n], [n, a, m, e], [[d, a, t, a, 1], [d, a, t, a, 2], [d, a, t, a, 3]]]], [Two, [LEVEL, [o, p, e, r, a, t, i, o, n], [n, a, m, e], []]], [Three, [LEVEL, [o, p, e, r, a, t, i, o, n], [n, a, m, e], [[d, a, t, a, 1], [d, a, t, a, 2]]]]]]</attributes>
</_schedule>
<success></success>
<attributes>[[[[One, [LEVEL, [o, p, e, r, a, t, i, o, n], [n, a, m, e], [[d, a, t, a, 1], [d, a, t, a, 2], [d, a, t, a, 3]]]], [Two, [LEVEL, [o, p, e, r, a, t, i, o, n], [n, a, m, e], []]], [Three, [LEVEL, [o, p, e, r, a, t, i, o, n], [n, a, m, e], [[d, a, t, a, 1], [d, a, t, a, 2]]]]]]]</attributes>
</_start>
Full Listing
Live On Coliru
//#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted.hpp>
#include <vector>
#include <map>
#include <set>
#include <iostream>
#include <iomanip>
#include <experimental/iterator>
enum class Level { One, Two, Three, LEVEL };
struct ComputeTask {
std::string dataname;
Level level;
std::string aggregator;
std::set<std::string> groupby;
};
struct Schedule {
std::map<Level, ComputeTask> tasks;
};
//////////////////////
// FOR DEBUG DEMO ONLY
static inline std::ostream& operator<<(std::ostream& os, Level l) {
switch(l) {
case Level::One: return os << "One";
case Level::Two: return os << "Two";
case Level::Three: return os << "Three";
case Level::LEVEL: return os << "LEVEL";
}
return os << "?";
}
static inline std::ostream& operator<<(std::ostream& os, ComputeTask const& task) {
os << task.level << ' ' << task.aggregator << ' ' << task.dataname << " on (";
copy(begin(task.groupby), end(task.groupby), std::experimental::make_ostream_joiner(os, ", "));
return os << ')';
}
/////////////
// FOR PARSER
BOOST_FUSION_ADAPT_STRUCT(ComputeTask, level, aggregator, dataname, groupby)
BOOST_FUSION_ADAPT_STRUCT(Schedule, tasks)
namespace qi = boost::spirit::qi;
template <typename It>
struct Parser : qi::grammar<It, Schedule()> {
Parser() : Parser::base_type(_start) {
using namespace qi;
_any_word = lexeme [ +char_("a-zA-Z0-9-_./") ];
_operation = _any_word; // TODO
_group_field = _any_word; // TODO
_dataname = _any_word; // TODO
_level = no_case [ _level_sym ];
_groupby = '(' >> -(_group_field % ',') >> ')';
_task = _level >> _operation >> _dataname >> "on" >> _groupby;
_entry = _level >> ':' >> _task;
_schedule = _entry % eol;
_start = skip(blank) [ _schedule ];
BOOST_SPIRIT_DEBUG_NODES((_start)(_schedule)(_task)(_groupby)(_level)(_operation)(_dataname)(_group_field))
}
private:
struct level_sym : qi::symbols<char, Level> {
level_sym() { this->add
("one", Level::One)
("two", Level::Two)
("three", Level::Three)
("level", Level::LEVEL);
}
} _level_sym;
// lexemes
qi::rule<It, std::string()> _any_word;
qi::rule<It, std::string()> _operation, _dataname, _group_field; // TODO
qi::rule<It, Level()> _level;
using Skipper = qi::blank_type;
using Table = decltype(Schedule::tasks);
using Entry = std::pair<Level, ComputeTask>;
qi::rule<It, std::set<std::string>(), Skipper> _groupby;
qi::rule<It, ComputeTask(), Skipper> _task;
qi::rule<It, Entry(), Skipper> _entry;
qi::rule<It, Table(), Skipper> _schedule;
qi::rule<It, Schedule()> _start;
};
int main() {
Parser<std::string::const_iterator> const parser;
for (std::string const input : { R"(ONE: level operation name on(data1, data2, data3)
TWO: level operation name on()
THREE: level operation name on(data1, data2))" })
{
auto f = begin(input), l = end(input);
Schedule s;
if (parse(f, l, parser, s)) {
std::cout << "Parsed\n";
for (auto& [level, task] : s.tasks) {
std::cout << level << ": " << task << "\n";
}
} else {
std::cout << "Failed\n";
}
if (f != l) {
std::cout << "Remaining unparsed input: " << std::quoted(std::string(f,l)) << "\n";
}
}
}
Koenig lookup and C++ requires a type specifier for all declarations
You have several errors:
Bad order of forward declaration:
namespace operators { // forward declare operators
struct in_t;
template<class E, class C>
bool named_invoke(E const &e, in_t, C const &container);
} // namespace operators
Bad operators:
template<class Lhs, class Op>
half_apply<Lhs, '<', Op> operator<(Lhs &&lhs, make_operator<Op>) {
return {std::forward<Lhs>(lhs)};
}
template<class Lhs, class Op, class Rhs>
auto operator>(half_apply<Lhs, '<', Op> &&lhs, Rhs &&rhs)
-> decltype(operators::named_invoke(std::forward<Lhs>(lhs.lhs), Op{}, std::forward<Rhs>(rhs))) {
return operators::named_invoke(std::forward<Lhs>(lhs.lhs), Op{}, std::forward<Rhs>(rhs));
}
but once fixed, it works. Demo.
Related Topics
Are There Any Better Methods to Do Permutation of String
How Does the Custom Deleter of Std::Unique_Ptr Work
How to Generate the Audio Spectrum Using Fft in C++
Can You Make Custom Operators in C++
How to Get the Number of Characters in a Std::String
Is There a Good Python Library That Can Parse C++
What Is the Correct Way of Reading from a Tcp Socket in C/C++
Mingw .Exe Requires a Few Gcc Dll's Regardless of the Code
Does Boost Have a Datatype for Set Operations That Is Simpler Than the Stl
How to Call a Function by Its Name (Std::String) in C++
Tools to Find Included Headers Which Are Unused
How to Sort a Std::Map First by Value, Then by Key
Visual Studio 2015 Doesn't Have Cl.Exe
The Copy Constructor and Assignment Operator
Are Static Variables in a Base Class Shared by All Derived Classes