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);
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.
hello guys i am new to maps in C++ i am having a question regarding copying a particular type map to another map of same kind the details are shown below
I initially declared a map like this
map<string,int> objmap,obj_porcess ;
for(int i = 0; i < 10; i++) {
objmap ["process"+to_string(i)]=i+10//some processing the to_string is just in case but i have strings with names for all 10 values
}
like
objmap["process_today"]=1;
objmap["process_yesterday"]=-1;
objmap["process_tommorow"]=2;
now i want to define some thing like this just my key word should be added with the process and remaining all can be same for all the keys from obj_process
obj_process["today"]=objmap["process_today"] ;
instead of defining all 10 can i have a simple code cause in here i took an example of 10 but i have like 200 set of different strings in the key of map
i already asked a qn for exact opposite one this was my previous qn now when i try its vice versa i got an issue hope i find some help
If you can initialize both at the same time, the solution is straightforward:
const std::vector<std::string> days = {"today", "yesterday", /*...*/};
for(const auto& d : days)
{
objmap["process_" + d] = foo();
obj_process[d] = foo();
}
If you cannot, you should be able to iterate over objmap and get rid of the "process_" prefix with some basic string manipulation:
constexpr auto prefix_length = 8; // length of "process_"
for (const auto& p : objmap)
{
const auto& key = p.first;
const auto& processed_key = key.substr(prefix_length);
obj_process[processed_key] = objmap[key];
}
first of all I admit I'm a newbie in C++ addons for node.js.
I'm writing my first addon and I reached a good result: the addon does what I want. I copied from various examples I found in internet to exchange complex data between the two languages, but I understood almost nothing of what I wrote.
The first thing scaring me is that I wrote nothing that seems to free some memory; another thing which is seriously worrying me is that I don't know if what I wrote may helps or creating confusion for the V8 garbage collector; by the way I don't know if there are better ways to do what I did (iterating over js Object keys in C++, creating js Objects in C++, creating Strings in C++ to be used as properties of js Objects and what else wrong you can find in my code).
So, before going on with my job writing the real math of my addon, I would like to share with the community the nan and V8 part of it to ask if you see something wrong or that can be done in a better way.
Thank you everybody for your help,
iCC
#include <map>
#include <nan.h>
using v8::Array;
using v8::Function;
using v8::FunctionTemplate;
using v8::Local;
using v8::Number;
using v8::Object;
using v8::Value;
using v8::String;
using Nan::AsyncQueueWorker;
using Nan::AsyncWorker;
using Nan::Callback;
using Nan::GetFunction;
using Nan::HandleScope;
using Nan::New;
using Nan::Null;
using Nan::Set;
using Nan::To;
using namespace std;
class Data {
public:
int dt1;
int dt2;
int dt3;
int dt4;
};
class Result {
public:
int x1;
int x2;
};
class Stats {
public:
int stat1;
int stat2;
};
typedef map<int, Data> DataSet;
typedef map<int, DataSet> DataMap;
typedef map<float, Result> ResultSet;
typedef map<int, ResultSet> ResultMap;
class MyAddOn: public AsyncWorker {
private:
DataMap *datas;
ResultMap results;
Stats stats;
public:
MyAddOn(Callback *callback, DataMap *set): AsyncWorker(callback), datas(set) {}
~MyAddOn() { delete datas; }
void Execute () {
for(DataMap::iterator i = datas->begin(); i != datas->end(); ++i) {
int res = i->first;
DataSet *datas = &i->second;
for(DataSet::iterator l = datas->begin(); l != datas->end(); ++l) {
int dt4 = l->first;
Data *data = &l->second;
// TODO: real population of stats and result
}
// test result population
results[res][res].x1 = res;
results[res][res].x2 = res;
}
// test stats population
stats.stat1 = 23;
stats.stat2 = 42;
}
void HandleOKCallback () {
Local<Object> obj;
Local<Object> res = New<Object>();
Local<Array> rslt = New<Array>();
Local<Object> sts = New<Object>();
Local<String> x1K = New<String>("x1").ToLocalChecked();
Local<String> x2K = New<String>("x2").ToLocalChecked();
uint32_t idx = 0;
for(ResultMap::iterator i = results.begin(); i != results.end(); ++i) {
ResultSet *set = &i->second;
for(ResultSet::iterator l = set->begin(); l != set->end(); ++l) {
Result *result = &l->second;
// is it ok to declare obj just once outside the cycles?
obj = New<Object>();
// is it ok to use same x1K and x2K instances for all objects?
Set(obj, x1K, New<Number>(result->x1));
Set(obj, x2K, New<Number>(result->x2));
Set(rslt, idx++, obj);
}
}
Set(sts, New<String>("stat1").ToLocalChecked(), New<Number>(stats.stat1));
Set(sts, New<String>("stat2").ToLocalChecked(), New<Number>(stats.stat2));
Set(res, New<String>("result").ToLocalChecked(), rslt);
Set(res, New<String>("stats" ).ToLocalChecked(), sts);
Local<Value> argv[] = { Null(), res };
callback->Call(2, argv);
}
};
NAN_METHOD(AddOn) {
Local<Object> datas = info[0].As<Object>();
Callback *callback = new Callback(info[1].As<Function>());
Local<Array> props = datas->GetOwnPropertyNames();
Local<String> dt1K = Nan::New("dt1").ToLocalChecked();
Local<String> dt2K = Nan::New("dt2").ToLocalChecked();
Local<String> dt3K = Nan::New("dt3").ToLocalChecked();
Local<Array> props2;
Local<Value> key;
Local<Object> value;
Local<Object> data;
DataMap *set = new DataMap();
int res;
int dt4;
DataSet *dts;
Data *dt;
for(uint32_t i = 0; i < props->Length(); i++) {
// is it ok to declare key, value, props2 and res just once outside the cycle?
key = props->Get(i);
value = datas->Get(key)->ToObject();
props2 = value->GetOwnPropertyNames();
res = To<int>(key).FromJust();
dts = &((*set)[res]);
for(uint32_t l = 0; l < props2->Length(); l++) {
// is it ok to declare key, data and dt4 just once outside the cycles?
key = props2->Get(l);
data = value->Get(key)->ToObject();
dt4 = To<int>(key).FromJust();
dt = &((*dts)[dt4]);
int dt1 = To<int>(data->Get(dt1K)).FromJust();
int dt2 = To<int>(data->Get(dt2K)).FromJust();
int dt3 = To<int>(data->Get(dt3K)).FromJust();
dt->dt1 = dt1;
dt->dt2 = dt2;
dt->dt3 = dt3;
dt->dt4 = dt4;
}
}
AsyncQueueWorker(new MyAddOn(callback, set));
}
NAN_MODULE_INIT(Init) {
Set(target, New<String>("myaddon").ToLocalChecked(), GetFunction(New<FunctionTemplate>(AddOn)).ToLocalChecked());
}
NODE_MODULE(myaddon, Init)
One year and half later...
If somebody is interested, my server is up and running since my question and the amount of memory it requires is stable.
I can't say if the code I wrote really does not has some memory leak or if lost memory is freed at each thread execution end, but if you are afraid as I was, I can say that using same structure and calls does not cause any real problem.
You do actually free up some of the memory you use, with the line of code:
~MyAddOn() { delete datas; }
In essence, C++ memory management boils down to always calling delete for every object created by new. There are also many additional architecture-specific and legacy 'C' memory management functions, but it is not strictly necessary to use these when you do not require the performance benefits.
As an example of what could potentially be a memory leak: You're passing the object held in the *callback pointer to the function AsyncQueueWorker. Yet nowhere in your code is this pointer freed, so unless the Queue worker frees it for you, there is a memory leak here.
You can use a memory tool such as valgrind to test your program further. It will spot most memory problems for you and comes highly recommended.
One thing I've observed is that you often ask (paraphrased):
Is it okay to declare X outside my loop?
To which the answer actually is that declaring variables inside of your loops is better, whenever you can do it. Declare variables as deep inside as you can, unless you have to re-use them. Variables are restricted in scope to the outermost set of {} brackets. You can read more about this in this question.
is it ok to use same x1K and x2K instances for all objects?
In essence, when you do this, if one of these objects modifies its 'x1K' string, then it will change for all of them. The advantage is that you free up memory. If the string is the same for all these objects anyway, instead of having to store say 1,000,000 copies of it, your computer will only keep a single one in memory and have 1,000,000 pointers to it instead. If the string is 9 ASCII characters long or longer under amd64, then that amounts to significant memory savings.
By the way, if you don't intend to modify a variable after its declaration, you can declare it as const, a keyword short for constant which forces the compiler to check that your variable is not modified after declaration. You may have to deal with quite a few compiler errors about functions accepting only non-const versions of things they don't modify, some of which may not be your own code, in which case you're out of luck. Being as conservative as possible with non-const variables can help spot problems.
I am looking at the lambda generators from https://stackoverflow.com/a/12735970 and https://stackoverflow.com/a/12639820.
I would like to adapt these to a template version and I'm wondering what I should return to signal that the generator has reached its end.
Consider
template<typename T>
std::function<T()> my_template_vector_generator(std::vector<T> &v) {
int idx = 0;
return [=,&v]() mutable {
return v[idx++];
};
}
The [=,&v] addition is mine and I hope it's correct. For now, it lets me change the vector outside as expected. Please comment on this if you have a bad feeling about it...
For reference, this works (REQUIRE is from catch):
std::vector<double> v({1.0, 2.0, 3.0});
auto vec_gen = my_template_vector_generator(v);
REQUIRE( vec_gen() == 1 );
REQUIRE( vec_gen() == 2 );
v[2] = 5.0;
REQUIRE( vec_gen() == 5.0 );
That vector version obviously requires knowledge of v.size() at the call site. I'd like to go without that by returning something that indicates the generator is empty.
Brainstorming, I can think of the following:
return pair<T, bool> and indicate false once there are no more values.
return iterators to the container values and iterate for (auto it=gen(); it!=gen.end(); it=gen()) {cout << *it << endl;}
wrapping the generator in a class and implementing an empty() method. Not entirely sure how that would work, however.
Does either of these versions feel good to you? Do you have another idea?
I'd particularly be interested in implications when mapping such a generator or combining them recursively (see this C++14 blog post for inspiration).
Update:
After hearing the optional suggestions, I implemented something based on unique_ptr.
template<typename T>
std::function<std::unique_ptr<T>()> my_pointer_template_vector_generator(std::vector<T> &v) {
int idx = 0;
return [=,&v]() mutable {
if (idx < v.size()) {
return std::unique_ptr<T>(new T(v[idx++]));
} else {
return std::unique_ptr<T>();
}
};
}
This seems to work, consider the following passing test.
TEST_CASE("Pointer generator terminates as expected") {
std::vector<double> v({1.0, 2.0, 3.0});
int k = 0;
auto gen = my_pointer_template_vector_generator(v);
while(auto val = gen()) {
REQUIRE( *val == v[k++] );
}
REQUIRE( v.size() == k );
}
I have some concerns about creating lots of new T. I suppose I could also return pointers into the vector and nullptr otherwise. That should work in the same way. What do you think about this?
As soon as it looks like just study example i could suggest to add exception as end of collection. But do not use it in real code.
I know that using atomics is dangerous (I watched Herb Sutter's 3hr lecture a few days ago), but the following use case seems reasonable to me, in terms of being simple and well contained.
Questions: (a) Is there something wrong with this? (Surely, there must be.) (b) Is there a name for this kind of hybrid atomic/mutex based approach? (c) Is there a simpler way of achieving the same thing?
The goal is to have a thread-safe counter class which we can call attempt_invalidation() on, knowing that it will only set its invalid flag to true if the count is at zero. There will be no other public methods on the class, but we will have a friend class specially designed to do RAII incrementing/decrementing of the counter.
class hybrid_counter{
friend class hybrid_counter_user;
bool invalidated = false;
int counter_a = 0;
std::atomic_int counter_b;
std::mutex mu;
bool increment_safely(){
std::lock_guard<std::mutex> gaurd(mu);
if ( !invalidated )
counter_a++;
return invalidated;
};
void increment_dangerously(){
counter_b++;
};
void decrement(){
counter_b--;
};
public:
bool attempt_invalidation(){
if(counter_a + counter_b == 0){
std::lock_guard<std::mutex> gaurd(mu);
if(counter_a + counter_b == 0)
invalidated = true;
}
return invalidated;
};
};
This is the friend class that knows how to use the counter correctly:
class hybrid_counter_user{
public:
hybrid_counter_user(hybrid_counter& hc){
if(hc.increment_safely() == false) // is not yet invalidated
c = &hc;
else
c = nullptr;
};
~hybrid_counter_user(){
if(c)
c->decrement();
};
hybrid_counter_user(hybrid_counter_user&& old){
c = old.c;
old.c = nullptr;
}
hybrid_counter_user(hybrid_counter_user& other){
c = other.c;
if(c)
c->increment_dangerously();
}
private:
hybrid_counter* c;
};
Note that the copy constructor uses the fact that hybrid_counter remains valid while other is in scope and other's destructor cannot be reordered with increment_dangerously because both involve the same atomic var.
The move constructor is simply transferring responsibility for decrementing.