If I have a
std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
variable, how can I define another time_point variable t2 such that it represents the time point exactly one second after of t1?
Something like auto t2 = t1 + "1s". What should I replace "1s" with?
If you are using C++14 (VS-2015, or -std=c++14 with gcc or clang), then:
using namespace std::chrono_literals;
auto t2 = t1 + 1s;
If you are using C++11:
using namespace std::chrono;
auto t2 = t1 + seconds{1};
If you don't want to make a copy, but add 1 second to t1 itself, += is also ok:
t1 += 1s;
t1 += seconds{1};
Related
I know how to calculate the total number of connected components in Boost, but is there an efficient way to compute the size of the largest connected component using the boost's graph library.
I think the most efficient way is to replace the component map with a custom type.
I created a small WritePropertyMap to do that:
template <typename V>
struct Mapper {
using Id = int; // component id
using Cardinality = int;
using Map = boost::container::flat_map<Id, Cardinality>;
using Value = Map::value_type;
Map& storage;
friend void put(Mapper& m, V const& /*v*/, Id id) { m.storage[id] += 1; }
Value largest() const {
return not storage.empty()
? *max_element(begin(storage), end(storage),
[](Value const& a, Value const& b) {
return a.second < b.second;
})
: Value{};
}
};
We need to tell Boost about our property map:
template <typename V> struct boost::property_traits<Mapper<V>> {
using category = boost::writable_property_map_tag;
using key_type = V;
using value_type = int;
};
Note
The separation between storage and property map is because property maps are passed by value - and should be cheap to copy.
Now we can use it, adapting the library example slightly:
Live On Coliru
Mapper<V>::Map result;
Mapper<V> mapper{result};
int num = connected_components(g, mapper);
auto [id, cardinality] = mapper.largest();
std::cout << "Largest component #" << id << " (out of " << num
<< " components) has " << cardinality << " vertices\n";
Prints
Largest component #0 (out of 3 components) has 3 vertices
This matches the expected output.
BONUS
If you have an expected number of components, you may be able to optimize storage by using small_vector/static_vector, e.g.
using Value = std::pair<Id, Cardinality>;
using Map = boost::container::flat_map<
Id, Cardinality, std::less<>,
boost::container::small_vector<Value, 10>>;
This way, unless you have more than 10 components, you will never see a dynamic allocation for the mapper storage.
std::XXX::inerator always support operator+, such as
const string s = "abcdef";
cout << *(s.begin() + 3);//output d
But ptree doesn't support operator+.
ptree p = root.get_child("insert");
//I want to directly goto the 3rd child.
auto iter = p.begin()+3;//error
I know I can use a for loop to do this. But I wonder if there is a more grace way to do this?
I achieved this by:
template <class InputIterator, class Distance>
void advance (InputIterator& it, Distance n);
C++ stl advance document
auto iter = p.begin();
advance(iter, 3);
how can I compare if the difference between 2 timpoints is greated than a certain fix time? I can mesure time but I do not manage to create a constant with the time I want.
So far I have the following code:
std::chrono::steady_clock::time_point t1= std::chrono::steady_clock::now();
...
std::chrono::steady_clock::time_point t2= std::chrono::steady_clock::now();
auto elapsedTime = std::chrono::duration_cast<std::chrono::milliseconds>(t2- t1);
i thought to create a constant and compare as follow:
std::chrono::milliseconds maxTime;
maxTime = 5000;
if(elapsedTime > maxTime){
//....
}
The assignment of maxTime does not work.
Any idea how to do so without passing the integer via the constructor)?
You can alter your code like:
std::chrono::steady_clock::time_point t1= std::chrono::steady_clock::now();
// ...
std::chrono::steady_clock::time_point t2= std::chrono::steady_clock::now();
auto elapsedTime = std::chrono::duration_cast<std::chrono::milliseconds>(t2-t1);
constexpr const std::chrono::milliseconds maxTime(5000); // <- this is the important change!
if(elapsedTime > maxTime){
//...
}
You have declared maxTime as std::chrono::milliseconds - that's why you cannot assign an int to it. If you have the amount of milliseconds that you want to assign to maxTime - let's call it int myAmount - use maxTime = std::chrono::milliseconds(myAmount); Of course, maxTime cannot be declared const then.
I need to map values to a std::string ( with the following map, and BOOST_FUSION_ADAPT_STRUCT )
std::map< TYPEX, std::string> author2name;
struct Emp
{
std::string name;
TYPEX author;
};
With the following code i want to generate my output:
karma::rule< it, std::string()> quote = '"' >> karma::string >> '"';
karma::rule< it, Emp> emp = karma::delimit('\t')[ quite << quite[ author2name[ karma::_1] ]];
Emp x;
karma::generate( std::ostream_iterator<char>(std::cout), emp, x);
But it doesn't compile.
And is there a way that i could write a header like this:
karma::rule< it, std::vector<std::string>()> header = karma::delimit('\t')[ % quote];
karma::rule< it, Emp> emp = header >> karma::eol >> karma::delimit('\t')[ quite << quite[ author2name[ karma::_1] ]];
karma::generate( std::ostream_iterator<char>(std::cout), {"A", "B", "C"},emp, x);
There is a number of small paper-cuts that killed you there :)
Working example:
Live On Coliru
#include <boost/fusion/adapted.hpp>
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <map>
namespace karma = boost::spirit::karma;
namespace phx = boost::phoenix;
enum TYPEX { AUTHOR1, AUTHOR2, AUTHOR3, AUTHOR4 };
std::map<TYPEX, std::string> author2name;
struct Emp {
std::string name;
TYPEX author;
};
BOOST_FUSION_ADAPT_STRUCT(Emp, name, author) // boost 1_59
//BOOST_FUSION_ADAPT_STRUCT(Emp, (std::string, name)(std::string, author)) // older boost
int main() {
using it = boost::spirit::ostream_iterator;
karma::rule<it, std::string()> quote;
karma::rule<it, TYPEX()> author;
karma::rule<it, Emp()> emp;
{
using namespace karma;
quote %= '"' << string << '"';
author = quote [ _1 = phx::ref(author2name)[ _val ] ];
emp %= delimit('\t')[ quote << author ];
}
Emp x { "one", AUTHOR2 };
author2name[AUTHOR2] = "TWO!";
std::cout << karma::format(emp, x);
}
Prints:
"one" "TWO!"
The things that caused trouble:
suggest to use boost::spirit::ostream_iterator and karma::format for more user-friendly API
Add the missing parentheses on emp:
karma::rule<it, Emp()> emp;
NOTE: very recent boost (1_59 IIRC) doesn't not require these anymore. Which is why I found out only on Coliru
Here:
quote[ author2name[ karma::_1] ]
you index [] into a std::map using ... qi::_1. That can't compile. What you wanted was to invoke the Phoenix lazy expression template of operator[]. You have to include the Phoenix header and force author2name to be a Phoenix reference actor:
quote [ _1 = phx::ref(author2name)[_1] ]
Note also, assigning back to _1 is important!
Also, to have an auto-rule in the presence of Semantic Actions, you need to assign the rule using %= (otherwise Karma will suppress all automatic attribute propagation)
I'm trying to parse a language where a unary minus is distinguished from a binary minus by the whitespaces existing around the sign. Below are some pseudo rules defining how the minus sign is interpreted in this language:
-x // unary
x - y // binary
x-y // binary
x -y // unary
x- y // binary
(- y ... // unary
Note: The open paren in the last rule can be replaced by any token in the language except 'identifier', 'number' and 'close_paren'.
Note: In the 4th case, x is an identifier. An identifier can constitue a statement of its own. And -y is a separate statement.
Since the minus sign type depends on whitespaces, I thought I'd have two different tokens returned from the lexer, one for unary minus and one for binary minus. Any ideas how can I do this?
Code: Here's some code that works for me, but I'm not quite sure if it's robust enough. I tried to make it simple by removing all the irrelevant lexer rules:
#ifndef LEXER_H
#define LEXER_H
#include <iostream>
#include <algorithm>
#include <string>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
#include <boost/spirit/include/phoenix_algorithm.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/include/phoenix_statement.hpp>
#define BOOST_SPIRIT_LEXERTL_DEBUG 1
using std::string;
using std::cerr;
namespace skill {
namespace lex = boost::spirit::lex;
namespace phoenix = boost::phoenix;
// base iterator type
typedef string::iterator BaseIteratorT;
// token type
typedef lex::lexertl::token<BaseIteratorT, boost::mpl::vector<int, string> > TokenT;
// lexer type
typedef lex::lexertl::actor_lexer<TokenT> LexerT;
template <typename LexerT>
struct Tokens: public lex::lexer<LexerT>
{
Tokens(const string& input):
lineNo_(1)
{
using lex::_start;
using lex::_end;
using lex::_pass;
using lex::_state;
using lex::_tokenid;
using lex::_val;
using lex::omit;
using lex::pass_flags;
using lex::token_def;
using phoenix::ref;
using phoenix::count;
using phoenix::construct;
// macros
this->self.add_pattern
("EXP", "(e|E)(\\+|-)?\\d+")
("SUFFIX", "[yzafpnumkKMGTPEZY]")
("INTEGER", "-?\\d+")
("FLOAT", "-?(((\\d+)|(\\d*\\.\\d+)|(\\d+\\.\\d*))({EXP}|{SUFFIX})?)")
("SYMBOL", "[a-zA-Z_?#](\\w|\\?|#)*")
("STRING", "\\\"([^\\\"]|\\\\\\\")*\\\"");
// whitespaces and comments
whitespaces_ = "\\s+";
comments_ = "(;[^\\n]*\\n)|(\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\/)";
// literals
float_ = "{FLOAT}";
integer_ = "{INTEGER}";
string_ = "{STRING}";
symbol_ = "{SYMBOL}";
// operators
plus_ = '+';
difference_ = '-';
minus_ = "-({SYMBOL}|\\()";
// ... more operators
// whitespace
this->self += whitespaces_
[
ref(lineNo_) += count(construct<string>(_start, _end), '\n'),
_pass = pass_flags::pass_ignore
];
// a minus between two identifiers, numbers or close-open parens is a binary minus, so add spaces around it
this->self += token_def<omit>("[)a-zA-Z?_0-9]-[(a-zA-Z?_0-9]")
[
unput(_start, _end, *_start + construct<string>(" ") + *(_start + 1) + " " + *(_start + 2)),
_pass = pass_flags::pass_ignore
];
// operators (except for close-brackets) cannot be followed by a binary minus
this->self += token_def<omit>("['`.+*<>/!~&|({\\[=,:#](\\s+-\\s*|\\s*-\\s+)")
[
unput(_start, _end, *_start + construct<string>("-")),
_pass = pass_flags::pass_ignore
];
// a minus directly preceding a symbol or an open paren is a unary minus
this->self += minus_
[
unput(_start, _end, construct<string>(_start + 1, _end)),
_val = construct<string>("-")
];
// literal rules
this->self += float_ | integer_ | string_ | symbol_;
// ... other rules
}
~Tokens() {}
size_t lineNo() { return lineNo_; }
// ignored tokens
token_def<omit> whitespaces_, comments_;
// literal tokens
token_def<int> integer_;
token_def<string> float_, symbol_, string_;
// operator tokens
token_def<> plus_, difference_, minus_; // minus_ is a unary minus
// ... other tokens
// current line number
size_t lineNo_;
};
}
#endif // LEXER_H
Basically, I defined a binary minus (called difference in the code) to be any minus sign that has whitespaces on both sides and used unput to ensure this rule. I also defined a unary minus as a minus sign that directly precedes a symbol or an open paren and again used unput to ensure this rule is maintained (for numbers, the minus sign is part of the token).