using range based for loop for iterating on a sub range - c++11

Is it possible to loop over sub range using range based for loop ?
std::vector <std::string> inputs={"1","abaaaa","abc","cda"};
for (auto &it : new_vector(inputs.begin()+1, inputs.end()))
{
// …
}

You could use Boost's iterator_range:
for (auto &it : boost::make_iterator_range(inputs.begin()+1, inputs.end()))
{
cout << it << endl;
}
demo
Alternatively you could write your own wrapper.

Unfortunately, there is no such thing in the C++ standard library. However, you can define your own wrapper like this (requires at least C++ 11 - which should not be problem in 2021):
template<typename Iter>
struct range
{
Iter b, e;
Iter begin() const { return b; }
Iter end() const { return e; }
};
template<typename T>
auto slice(const T& c, std::size_t from, std::size_t to = -1) -> range<decltype(c.begin())>
{
to = (to > c.size() ? c.size() : to);
return range<decltype(c.begin())>{c.begin() + from, c.begin() + to};
}
And then you can use it:
std::vector<int> items(100);
// Iterates from 4th to 49th item
for (auto x: slice(items, 4, 50))
{
}
// Iterates from 15th to the last item
for (auto x: slice(items, 15))
{
}

tl;dr
Long story short, you #include <range/v3/view/subrange.hpp> and change your new_vector to ranges::subrange. And that's it. Demo on Compiler Explorer.
So
Given the name you imagine for this function, new_vector, maybe you think you need the entity on the right of : to be a std::vector or at least some type of container.
If that's the case, then change your mind, it's not needed. All that : wants from its "right hand side" is that it have begin and end defined on them, member or non member. For instance, this compiles and runs just fine:
struct A {};
int* begin(A);
int* end(A);
struct B {
int* begin();
int* end();
};
int main()
{
for (auto it : A{}) {}
for (auto it : B{}) {}
}

Related

Variadic Template Recursion

I am trying to use recursion to solve this problem where if i call
decimal<0,0,1>();
i should get the decimal number (4 in this case).
I am trying to use recursion with variadic templates but cannot get it to work.
Here's my code;
template<>
int decimal(){
return 0;
}
template<bool a,bool...pack>
int decimal(){
cout<<a<<"called"<<endl;
return a*2 + decimal<pack...>();
};
int main(int argc, char *argv[]){
cout<<decimal<0,0,1>()<<endl;
return 0;
}
What would be the best way to solve this?
template<typename = void>
int decimal(){
return 0;
}
template<bool a,bool...pack>
int decimal(){
cout<<a<<"called"<<endl;
return a + 2*decimal<pack...>();
};
The problem was with the recursive case, where it expects to be able to call decltype<>(). That is what I have defined in the first overload above. You can essentially ignore the typename=void, the is just necessary to allow the first one to compile.
A possible solution can be the use of a constexpr function (so you can use it's values it's value run-time, when appropriate) where the values are argument of the function.
Something like
#include <iostream>
constexpr int decimal ()
{ return 0; }
template <typename T, typename ... packT>
constexpr int decimal (T const & a, packT ... pack)
{ return a*2 + decimal(pack...); }
int main(int argc, char *argv[])
{
constexpr int val { decimal(0, 0, 1) };
static_assert( val == 2, "!");
std::cout << val << std::endl;
return 0;
}
But I obtain 2, not 4.
Are you sure that your code should return 4?
-- EDIT --
As pointed by aschepler, my example decimal() template function return "eturns twice the sum of its arguments, which is not" what do you want.
Well, with 0, 1, true and false you obtain the same; with other number, you obtain different results.
But you can modify decimal() as follows
template <typename ... packT>
constexpr int decimal (bool a, packT ... pack)
{ return a*2 + decimal(pack...); }
to avoid this problem.
This is a C++14 solution. It is mostly C++11, except for std::integral_sequence nad std::index_sequence, both of which are relatively easy to implement in C++11.
template<bool...bs>
using bools = std::integer_sequence<bool, bs...>;
template<std::uint64_t x>
using uint64 = std::integral_constant< std::uint64_t, x >;
template<std::size_t N>
constexpr uint64< ((std::uint64_t)1) << (std::uint64_t)N > bit{};
template<std::uint64_t... xs>
struct or_bits : uint64<0> {};
template<std::int64_t x0, std::int64_t... xs>
struct or_bits<x0, xs...> : uint64<x0 | or_bits<xs...>{} > {};
template<bool...bs, std::size_t...Is>
constexpr
uint64<
or_bits<
uint64<
bs?bit<Is>:std::uint64_t(0)
>{}...
>{}
>
from_binary( bools<bs...> bits, std::index_sequence<Is...> ) {
(void)bits; // suppress warning
return {};
}
template<bool...bs>
constexpr
auto from_binary( bools<bs...> bits={} )
-> decltype( from_binary( bits, std::make_index_sequence<sizeof...(bs)>{} ) )
{ return {}; }
It generates the resulting value as a type with a constexpr conversion to scalar. This is slightly more powerful than a constexpr function in its "compile-time-ness".
It assumes that the first bit is the most significant bit in the list.
You can use from_binary<1,0,1>() or from_binary( bools<1,0,1>{} ).
Live example.
This particular style of type-based programming results in code that does all of its work in its signature. The bodies consist of return {};.

How to skip the first element of the vector and iterate from second using range based for loops [duplicate]

I have a std::vector<std::string> v; (initialized). How can I use the range-for loop for accessing all elements except the first one (on index zero). For all elements:
for (const string & s: v)
process(s);
Instead of the v a range expression can be used. How can I write the range expression to skip the first element (or skip the first n elements)?
I know how to get the effect using v.begin() + 1 and using the classic loop. I am searching for the new, more readable, recommended alternative to do that. Possibly something similar to Python slicing? ...like:
for s in v[1:]:
process(s)
Until ranges make it into the standard library, you won't get any better than a vanilla for loop in plain C++ :
for(auto i = begin(v) + 1, e = end(v); i !=e; ++i)
// Do something with *i
Create a wrapper for which begin() and end() return the correct iterators and then you can use that as the second argument.
#include <iostream>
#include <vector>
template< typename Collection >
class FromNth
{
Collection& coll_;
size_t offset_;
public:
FromNth( Collection& coll, size_t offset )
: coll_( coll ), offset_( offset )
{
}
// will nicely resolve to const_iterator if necessary
auto begin() const -> decltype( coll_.begin() )
{ return coll_.begin() + offset_; }
auto end() const -> decltype( coll_.end() )
{ return coll_.end(); }
};
template< typename Collection >
FromNth<Collection> makeFromNth( Collection& collection, size_t offset )
{
return FromNth<Collection>( collection, offset );
}
template< typename Collection >
auto begin( const FromNth<Collection> & wrapper ) -> decltype( wrapper.begin() )
{
return wrapper.begin();
}
template< typename Collection >
auto end( const FromNth<Collection> & wrapper ) -> decltype( wrapper.end() )
{
return wrapper.end();
}
int main()
{
std::vector< int > coll { 2, 3, 5, 7, 11, 13, 17, 19, 23 };
for( auto x : makeFromNth( coll, 1 ) )
{
std::cout << x << '\n';
}
return 0;
}
Note that my fromNth "begin" is undefined behaviour if the size of the input is less than the offset. (If it's equal then it's well defined and begin == end). Therefore do a size check first.
Note: if you are using a recent enough version of boost then iterator_range may already provide you such a "collection" that is similar to my "FromNth".
for( auto const& s : boost::make_iterator_range( v.begin() + 1, v.end() ) )
{
process( s );
}
Note: the code above worked on CodingGround using C++11 GNU 4.8.3. (That site is very slow though). From C++14 you will not need the ->decltype statements (which are needed in C++11 for templates).
Output:
sh-4.3$ g++ -std=c++11 -o main *.cpp
sh-4.3$ main
3
5
7
11
13
17
19
23

iterator over non-existing sequence

I have K objects (K is small, e.g. 2 or 5) and I need to iterate over them N times in random order where N may be large. I need to iterate in a foreach loop and for this I should provide an iterator.
So far I created a std::vector of my K objects copied accordingly, so the size of vector is N and now I use begin() and end() provided by that vector. I use std::shuffle() to randomize the vector and this takes up to 20% of running time. I think it would be better (and more elegant, anyways) to write a custom iterator that returns one of my object in random order without creating the helping vector of size N. But how to do this?
It is obvious that your iterator must:
Store pointer to original vector or array: m_pSource
Store the count of requests (to be able to stop): m_nOutputCount
Use random number generator (see random): m_generator
Some iterator must be treated as end iterator: m_nOutputCount == 0
I've made an example for type int:
#include <iostream>
#include <random>
class RandomIterator: public std::iterator<std::forward_iterator_tag, int>
{
public:
//Creates "end" iterator
RandomIterator() : m_pSource(nullptr), m_nOutputCount(0), m_nCurValue(0) {}
//Creates random "start" iterator
RandomIterator(const std::vector<int> &source, int nOutputCount) :
m_pSource(&source), m_nOutputCount(nOutputCount + 1),
m_distribution(0, source.size() - 1)
{
operator++(); //make new random value
}
int operator* () const
{
return m_nCurValue;
}
RandomIterator operator++()
{
if (m_nOutputCount == 0)
return *this;
--m_nOutputCount;
static std::default_random_engine generator;
static bool bWasGeneratorInitialized = false;
if (!bWasGeneratorInitialized)
{
std::random_device rd; //expensive calls
generator.seed(rd());
bWasGeneratorInitialized = true;
}
m_nCurValue = m_pSource->at(m_distribution(generator));
return *this;
}
RandomIterator operator++(int)
{ //postincrement
RandomIterator tmp = *this;
++*this;
return tmp;
}
int operator== (const RandomIterator& other) const
{
if (other.m_nOutputCount == 0)
return m_nOutputCount == 0; //"end" iterator
return m_pSource == other.m_pSource;
}
int operator!= (const RandomIterator& other) const
{
return !(*this == other);
}
private:
const std::vector<int> *m_pSource;
int m_nOutputCount;
int m_nCurValue;
std::uniform_int_distribution<std::vector<int>::size_type> m_distribution;
};
int main()
{
std::vector<int> arrTest{ 1, 2, 3, 4, 5 };
std::cout << "Original =";
for (auto it = arrTest.cbegin(); it != arrTest.cend(); ++it)
std::cout << " " << *it;
std::cout << std::endl;
RandomIterator rndEnd;
std::cout << "Random =";
for (RandomIterator it(arrTest, 15); it != rndEnd; ++it)
std::cout << " " << *it;
std::cout << std::endl;
}
The output is:
Original = 1 2 3 4 5
Random = 1 4 1 3 2 4 5 4 2 3 4 3 1 3 4
You can easily convert it into a template. And make it to accept any random access iterator.
I just want to increment Dmitriy answer, because reading your question, it seems that you want that every time that you iterate your newly-created-and-shuffled collection the items should not repeat and Dmitryi´s answer does have repetition. So both iterators are useful.
template <typename T>
struct RandomIterator : public std::iterator<std::forward_iterator_tag, typename T::value_type>
{
RandomIterator() : Data(nullptr)
{
}
template <typename G>
RandomIterator(const T &source, G& g) : Data(&source)
{
Order = std::vector<int>(source.size());
std::iota(begin(Order), end(Order), 0);
std::shuffle(begin(Order), end(Order), g);
OrderIterator = begin(Order);
OrderIteratorEnd = end(Order);
}
const typename T::value_type& operator* () const noexcept
{
return (*Data)[*OrderIterator];
}
RandomIterator<T>& operator++() noexcept
{
++OrderIterator;
return *this;
}
int operator== (const RandomIterator<T>& other) const noexcept
{
if (Data == nullptr && other.Data == nullptr)
{
return 1;
}
else if ((OrderIterator == OrderIteratorEnd) && (other.Data == nullptr))
{
return 1;
}
return 0;
}
int operator!= (const RandomIterator<T>& other) const noexcept
{
return !(*this == other);
}
private:
const T *Data;
std::vector<int> Order;
std::vector<int>::iterator OrderIterator;
std::vector<int>::iterator OrderIteratorEnd;
};
template <typename T, typename G>
RandomIterator<T> random_begin(const T& v, G& g) noexcept
{
return RandomIterator<T>(v, g);
}
template <typename T>
RandomIterator<T> random_end(const T& v) noexcept
{
return RandomIterator<T>();
}
whole code at
http://coliru.stacked-crooked.com/a/df6ce482bbcbafcf or
https://github.com/xunilrj/sandbox/blob/master/sources/random_iterator/source/random_iterator.cpp
Implementing custom iterators can be very tricky so I tried to follow some tutorials, but please let me know if something have passed:
http://web.stanford.edu/class/cs107l/handouts/04-Custom-Iterators.pdf
https://codereview.stackexchange.com/questions/74609/custom-iterator-for-a-linked-list-class
Operator overloading
I think that the performance is satisfactory:
On the Coliru:
<size>:<time for 10 iterations>
1:0.000126582
10:3.5179e-05
100:0.000185914
1000:0.00160409
10000:0.0161338
100000:0.180089
1000000:2.28161
Off course it has the price to allocate a whole vector with the orders, that is the same size of the original vector.
An improvement would be to pre-allocate the Order vector if for some reason you have to random iterate very often and allow the iterator to use this pre-allocated vector, or some form of reset() in the iterator.

Boost.Variant Vs Virtual Interface Performance

I'm trying to measure a performance difference between using Boost.Variant and using virtual interfaces. For example, suppose I want to increment different types of numbers uniformly, using Boost.Variant I would use a boost::variant over int and float and a static visitor which increments each one of them. Using class interfaces I would use a pure virtual class number and number_int and number_float classes which derive from it and implement an "increment" method.
From my testing, using interfaces is far faster than using Boost.Variant.
I ran the code at the bottom and received these results:
Virtual: 00:00:00.001028
Variant: 00:00:00.012081
Why do you suppose this difference is? I thought Boost.Variant would be a lot faster.
** Note: Usually Boost.Variant uses heap allocations to guarantee that the variant would always be non-empty. But I read on the Boost.Variant documentation that if boost::has_nothrow_copy is true then it doesn't use heap allocations which should make things significantly faster. For int and float boost::has_nothrow_copy is true.
Here is my code for measuring the two approaches against each other.
#include <iostream>
#include <boost/variant/variant.hpp>
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <boost/date_time/posix_time/ptime.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>
#include <boost/format.hpp>
const int iterations_count = 100000;
// a visitor that increments a variant by N
template <int N>
struct add : boost::static_visitor<> {
template <typename T>
void operator() (T& t) const {
t += N;
}
};
// a number interface
struct number {
virtual void increment() = 0;
};
// number interface implementation for all types
template <typename T>
struct number_ : number {
number_(T t = 0) : t(t) {}
virtual void increment() {
t += 1;
}
T t;
};
void use_virtual() {
number_<int> num_int;
number* num = &num_int;
for (int i = 0; i < iterations_count; i++) {
num->increment();
}
}
void use_variant() {
typedef boost::variant<int, float, double> number;
number num = 0;
for (int i = 0; i < iterations_count; i++) {
boost::apply_visitor(add<1>(), num);
}
}
int main() {
using namespace boost::posix_time;
ptime start, end;
time_duration d1, d2;
// virtual
start = microsec_clock::universal_time();
use_virtual();
end = microsec_clock::universal_time();
// store result
d1 = end - start;
// variant
start = microsec_clock::universal_time();
use_variant();
end = microsec_clock::universal_time();
// store result
d2 = end - start;
// output
std::cout <<
boost::format(
"Virtual: %1%\n"
"Variant: %2%\n"
) % d1 % d2;
}
For those interested, after I was a bit frustrated, I passed the option -O2 to the compiler and boost::variant was way faster than a virtual call.
Thanks
This is obvious that -O2 reduces the variant time, because that whole loop is optimized away. Change the implementation to return the accumulated result to the caller, so that the optimizer wouldn't remove the loop, and you'll get the real difference:
Output:
Virtual: 00:00:00.000120 = 10000000
Variant: 00:00:00.013483 = 10000000
#include <iostream>
#include <boost/variant/variant.hpp>
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <boost/date_time/posix_time/ptime.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>
#include <boost/format.hpp>
const int iterations_count = 100000000;
// a visitor that increments a variant by N
template <int N>
struct add : boost::static_visitor<> {
template <typename T>
void operator() (T& t) const {
t += N;
}
};
// a visitor that increments a variant by N
template <typename T, typename V>
T get(const V& v) {
struct getter : boost::static_visitor<T> {
T operator() (T t) const { return t; }
};
return boost::apply_visitor(getter(), v);
}
// a number interface
struct number {
virtual void increment() = 0;
};
// number interface implementation for all types
template <typename T>
struct number_ : number {
number_(T t = 0) : t(t) {}
virtual void increment() { t += 1; }
T t;
};
int use_virtual() {
number_<int> num_int;
number* num = &num_int;
for (int i = 0; i < iterations_count; i++) {
num->increment();
}
return num_int.t;
}
int use_variant() {
typedef boost::variant<int, float, double> number;
number num = 0;
for (int i = 0; i < iterations_count; i++) {
boost::apply_visitor(add<1>(), num);
}
return get<int>(num);
}
int main() {
using namespace boost::posix_time;
ptime start, end;
time_duration d1, d2;
// virtual
start = microsec_clock::universal_time();
int i1 = use_virtual();
end = microsec_clock::universal_time();
// store result
d1 = end - start;
// variant
start = microsec_clock::universal_time();
int i2 = use_variant();
end = microsec_clock::universal_time();
// store result
d2 = end - start;
// output
std::cout <<
boost::format(
"Virtual: %1% = %2%\n"
"Variant: %3% = %4%\n"
) % d1 % i1 % d2 % i2;
}

Implementing equivalence relations in C++ (using boost::disjoint_sets)

Assume you have many elements, and you need to keep track of the equivalence relations between them. If element A is equivalent to element B, it is equivalent to all the other elements B is equivalent to.
I am looking for an efficient data structure to encode this information. It should be possible to dynamically add new elements through an equivalence with an existing element, and from that information it should be possible to efficiently compute all the elements the new element is equivalent to.
For example, consider the following equivalence sets of the elements [0,1,2,3,4]:
0 = 1 = 2
3 = 4
where the equality sign denotes equivalence. Now we add a new element 5
0 = 1 = 2
3 = 4
5
and enforcing the equivalence 5=3, the data structure becomes
0 = 1 = 2
3 = 4 = 5
From this, one should be able to iterate efficiently through the equivalence set for any element. For 5, this set would be [3,4,5].
Boost already provides a convenient data structure called disjoint_sets that seems to meet most of my requirements. Consider this simple program that illustates how to implement the above example:
#include <cstdio>
#include <vector>
#include <boost/pending/disjoint_sets.hpp>
#include <boost/unordered/unordered_set.hpp>
/*
Equivalence relations
0 = 1 = 2
3 = 4
*/
int main(int , char* [])
{
typedef std::vector<int> VecInt;
typedef boost::unordered_set<int> SetInt;
VecInt rank (100);
VecInt parent (100);
boost::disjoint_sets<int*,int*> ds(&rank[0], &parent[0]);
SetInt elements;
for (int i=0; i<5; ++i) {
ds.make_set(i);
elements.insert(i);
}
ds.union_set(0,1);
ds.union_set(1,2);
ds.union_set(3,4);
printf("Number of sets:\n\t%d\n", (int)ds.count_sets(elements.begin(), elements.end()));
// normalize set so that parent is always the smallest number
ds.normalize_sets(elements.begin(), elements.end());
for (SetInt::const_iterator i = elements.begin(); i != elements.end(); ++i) {
printf("%d %d\n", *i, ds.find_set(*i));
}
return 0;
}
As seen above one can efficiently add elements, and dynamically expand the disjoint sets. How can one efficiently iterate over the elements of a single disjoint set, without having to iterate over all the elements?
Most probably you can't do that, disjoint_sets doesn't support iteration over one set only. The underlying data structure and algorithms wouldn't be able to do it efficiently anyway, i.e. even if there was support built in to disjoint_sets for iteration over one set only, that would be just as slow as iterating over all sets, and filtering out wrong sets.
Either I am missing something, you forgot to mention something, or maybe you were overthinking this ;)
Happily, equivalence is not equality. For A & B to be equivalent; they only need to share an attribute with the same value. this could be a scalar or even a vector. Anyway, I think your posted requirements can be achieved just using std::multiset and it's std::multiset::equal_range() member function.
//////////////////////////////////////
class E
{
//could be a GUID or something instead but the time complexity of
//std::multiset::equal_range with a simple int comparison should be logarithmic
static size_t _faucet;
public:
struct LessThan
{
bool operator()(const E* l, const E* r) const { return (l->eqValue() < r->eqValue()); }
};
using EL=std::vector<const E*>;
using ES=std::multiset<const E*, E::LessThan>;
using ER=std::pair<ES::iterator, ES::iterator>;
static size_t NewValue() { return ++_faucet; }
~E() { eqRemove(); }
E(size_t val) : _eqValue(val) {}
E(std::string name) : Name(name), _eqValue(NewValue()) { E::Elementals.insert(this); }
//not rly a great idea to use operator=() for this. demo only..
const E& operator=(const class E& other) { eqValue(other); return *this; }
//overriddable default equivalence interface
virtual size_t eqValue() const { return _eqValue; };
//clearly it matters how mutable you need your equivalence relationships to be,,
//in this implementation, if an element's equivalence relation changes then
//the element is going to be erased and re-inserted.
virtual void eqValue(const class E& other)
{
if (_eqValue == other._eqValue) return;
eqRemove();
_eqValue=other._eqValue;
E::Elementals.insert(this);
};
ES::iterator eqRemove()
{
auto range=E::Elementals.equal_range(this);
//worst-case complexity should be aprox linear over the range
for (auto it=range.first; it!=range.second; it++)
if (this == (*it))
return E::Elementals.erase(it);
return E::Elementals.end();
}
std::string Name; //some other attribute unique to the instance
static ES Elementals; //canonical set of elements with equivalence relations
protected:
size_t _eqValue=0;
};
size_t E::_faucet=0;
E::ES E::Elementals{};
//////////////////////////////////////
//random specialisation providing
//dynamic class-level equivalence
class StarFish : public E
{
public:
static void EqAssign(const class E& other)
{
if (StarFish::_id == other.eqValue()) return;
E el(StarFish::_id);
auto range=E::Elementals.equal_range(&el);
StarFish::_id=other.eqValue();
E::EL insertList(range.first, range.second);
E::Elementals.erase(range.first, range.second);
E::Elementals.insert(insertList.begin(), insertList.end());
}
StarFish() : E("starfish") {}
//base-class overrides
virtual size_t eqValue() const { return StarFish::_id; };
protected: //equivalence is a the class level
virtual void eqValue(const class E& other) { assert(0); }
private:
static size_t _id;
};
size_t StarFish::_id=E::NewValue();
//////////////////////////////////////
void eqPrint(const E& e)
{
std::cout << std::endl << "elementals equivalent to " << e.Name << ": ";
auto range=E::Elementals.equal_range(&e);
for (auto it=range.first; it!=range.second; it++)
std::cout << (*it)->Name << " ";
std::cout << std::endl << std::endl;
}
//////////////////////////////////////
void eqPrint()
{
for (auto it=E::Elementals.begin(); it!=E::Elementals.end(); it++)
std::cout << (*it)->Name << ": " << (*it)->eqValue() << " ";
std::cout << std::endl << std::endl;
}
//////////////////////////////////////
int main()
{
E e0{"zero"}, e1{"one"}, e2{"two"}, e3{"three"}, e4{"four"}, e5{"five"};
//per the OP
e0=e1=e2;
e3=e4;
e5=e3;
eqPrint(e0);
eqPrint(e3);
eqPrint(e5);
eqPrint();
StarFish::EqAssign(e3);
StarFish starfish1, starfish2;
starfish1.Name="fred";
eqPrint(e3);
//re-assignment
StarFish::EqAssign(e0);
e3=e0;
{ //out of scope removal
E e6{"six"};
e6=e4;
eqPrint(e4);
}
eqPrint(e5);
eqPrint(e0);
eqPrint();
return 0;
}
online demo
NB: C++ class inheritance also provides another kind of immutable equivalence that can be quite useful ;)

Resources