Commit ecab6f46 authored by Anton Bukov's avatar Anton Bukov

Reimplemented a lot, has a compiler infinite recursion

parent a32c5293
...@@ -7,3 +7,5 @@ ipch ...@@ -7,3 +7,5 @@ ipch
*.suo *.suo
[Bb]uild* [Bb]uild*
nbproject nbproject
.idea
cmake-build-debug
//
// Copyright (C) <year> <copyright holders>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#pragma once #pragma once
#include <set>
#include <list>
#include <deque>
#include <string>
#include <vector>
#include <iostream>
#include <functional> #include <functional>
#include <climits>
namespace boolinq #include <iterator>
{ #include <iostream>
//////////////////////////////////////////////////////////////// #include <vector>
// Enumerator template #include <list>
//////////////////////////////////////////////////////////////// #include <unordered_set>
class EnumeratorEndException {}; //
template<typename T, typename S> namespace boolinq {
class Enumerator
{
std::function<T(S&)> _nextObject;
S _data;
public: struct LinqEndException {};
typedef T value_type;
Enumerator(std::function<T(S&)> nextObject, S data)
: _nextObject(nextObject)
, _data(data)
{
}
T nextObject() enum BytesDirection {
{ BytesFirstToLast,
return _nextObject(_data); BytesLastToFirst,
}
}; };
template<typename T, typename S> enum BitsDirection {
std::ostream & operator << (std::ostream & stream, Enumerator<T,S> enumerator) BitsHighToLow,
{ BitsLowToHigh,
try };
{
for (;;)
stream << enumerator.nextObject() << ' ';
}
catch(EnumeratorEndException &) {}
return stream;
}
////////////////////////////////////////////////////////////////
// Iterator and Container pair
////////////////////////////////////////////////////////////////
template<typename TI, typename TC> template<typename S, typename T>
class IteratorContainerPair class Linq {
{ std::function<T(S &)> nextFunc;
std::function<TI(const TC &)> get_ti; S storage;
public: public:
TC second; typedef T value_type;
TI first;
IteratorContainerPair(const TC & tc, std::function<TI(const TC &)> get_ti_)
: get_ti(get_ti_)
, second(tc)
, first(get_ti(second))
{
}
IteratorContainerPair(const IteratorContainerPair<TI,TC> & pair) Linq() : nextFunc(), storage()
: get_ti(pair.get_ti)
, second(pair.second)
, first(get_ti(second))
{ {
for (auto it = pair.get_ti(pair.second); it != pair.first; ++it)
first++;
} }
};
////////////////////////////////////////////////////////////////
// Linq methods implementation
////////////////////////////////////////////////////////////////
enum BytesDirection Linq(S storage, std::function<T(S &)> nextFunc) : nextFunc(nextFunc), storage(storage)
{
FirstToLast,
LastToFirst,
};
enum BitsDirection
{
HighToLow,
LowToHigh,
};
template<typename TE>
class LinqObj
{
typedef typename TE::value_type T;
template<typename TFunc, typename TArg>
static auto get_return_type(TFunc * func = NULL, TArg * arg1 = NULL)
-> decltype((*func)(*arg1));
template<typename TFunc, typename T1Arg, typename T2Arg>
static auto get_return_type(TFunc * func = NULL, T1Arg * arg1 = NULL, T2Arg * arg2 = NULL)
-> decltype((*func)(*arg1,*arg2));
public:
TE _enumerator;
typedef typename TE::value_type value_type;
LinqObj(TE enumerator)
: _enumerator(enumerator)
{ {
} }
T nextObject() T next()
{ {
return _enumerator.nextObject(); return nextFunc(storage);
} }
// Main methods template<typename SS, typename TT>
struct LinqIndex {
Linq<SS, TT> linq;
int index;
};
void foreach_i(std::function<void(T,int)> action) const void foreach_i(std::function<void(T, int)> apply) const
{ {
auto en = _enumerator; LinqIndex<S, T> storage = {*this, 0};
int index = 0; try {
try while (true) {
{ apply(storage.linq.next(), storage.index++);
for (;;) }
action(en.nextObject(), index++);
} }
catch(EnumeratorEndException &) {} catch (LinqEndException &) {}
} }
void foreach(std::function<void(T)> action) const void foreach(std::function<void(T)> apply) const
{ {
foreach_i([=](T a, int){return action(a);}); return foreach_i([apply](T &&value, int index) { return apply(value); });
} }
LinqObj<Enumerator<T,std::pair<TE,int> > > where_i(std::function<bool(T,int)> predicate) const Linq<LinqIndex<S, T>, T> where_i(std::function<bool(T, int)> filter) const
{ {
return Enumerator<T,std::pair<TE,int> >([=](std::pair<TE,int> & pair)->T{ return Linq<LinqIndex<S, T>, T>(
T object; {*this, 0},
do [filter](auto &pair) {
object = pair.first.nextObject(); while (true) {
while (!predicate(object, pair.second++)); T ret = pair.linq.next();
return object; if (filter(ret, pair.index++)) {
}, std::make_pair(_enumerator,0)); return ret;
}
}
}
);
} }
LinqObj<Enumerator<T,std::pair<TE,int> > > where(std::function<bool(T)> predicate) const Linq<LinqIndex<S, T>, T> where(std::function<bool(T)> filter) const
{ {
return where_i([=](T a, int){return predicate(a);}); return where_i([filter](T &&value, int index) { return filter(value); });
} }
LinqObj<Enumerator<T,std::pair<TE,int> > > take(int count) const Linq<LinqIndex<S, T>, T> take(int count) const
{ {
return where_i([=](T, int i){ return where_i([count](T /*value*/, int i) {
if(i == count) if (i == count) {
throw EnumeratorEndException(); throw LinqEndException();
}
return true; return true;
}); });
} }
LinqObj<Enumerator<T,std::pair<TE,int> > > takeWhile_i(std::function<bool(T,int)> predicate) const Linq<LinqIndex<S, T>, T> takeWhile_i(std::function<bool(T, int)> predicate) const
{ {
return Enumerator<T,std::pair<TE,int> >([=](std::pair<TE,int> & pair)->T{ return where_i([predicate](T &&value, int i) {
T object = pair.first.nextObject(); if (!predicate(value, i)) {
if(!predicate(object,pair.second++)) throw EnumeratorEndException(); throw LinqEndException();
return object; }
}, std::make_pair(_enumerator,0)); return true;
});
} }
LinqObj<Enumerator<T,std::pair<TE,int> > > takeWhile(std::function<bool(T)> predicate) const Linq<LinqIndex<S, T>, T> takeWhile(std::function<bool(T)> predicate) const
{ {
return takeWhile_i([=](T t,int){return predicate(t);}); return takeWhile_i([predicate](T &&value, int /*i*/) { return predicate(value); });
} }
LinqObj<Enumerator<T,std::pair<TE,int> > > skip(int count) const Linq<LinqIndex<S, T>, T> skip(int count) const
{ {
return where_i([=](T, int i){return i >= count;}); return where_i([count](T &&value, int i) { return i >= count; });
} }
LinqObj<Enumerator<T,std::pair<TE,int> > > skipWhile_i(std::function<bool(T,int)> predicate) const template<typename SS, typename TT>
{ struct LinqIndexFlag : public LinqIndex<SS, TT> {
return Enumerator<T,std::pair<TE,int> >([=](std::pair<TE,int> & pair)->T{ bool flag;
if (pair.second != 0) };
return pair.first.nextObject();
T object;
do
object = pair.first.nextObject();
while (predicate(object,pair.second++));
return object; Linq<LinqIndexFlag<S, T>, T> skipWhile_i(std::function<bool(T, int)> predicate) const
}, std::make_pair(_enumerator,0)); {
return Linq<LinqIndexFlag<S, T>, T>(
{*this, 0, false},
[predicate](auto &tuple) {
if (tuple.flag) {
return tuple.linq.next();
}
while (true) {
T ret = tuple.linq.next();
if (predicate(ret, tuple.index++)) {
return ret;
}
}
}
);
} }
LinqObj<Enumerator<T,std::pair<TE,int> > > skipWhile(std::function<bool(T)> predicate) const Linq<LinqIndexFlag<S, T>, T> skipWhile(std::function<bool(T)> predicate) const
{ {
return skipWhile_i([=](T t, int /*i*/){ return predicate(t);}); return skipWhile_i([predicate](T &&value, int /*i*/) { return predicate(value); });
} }
template<typename TRet> template<typename F, typename _TRet = typename std::result_of<F(T, int)>::type>
LinqObj<Enumerator<TRet,std::pair<TE,int> > > select_i(std::function<TRet(T,int)> transform) const auto select_i(F apply) const -> Linq<LinqIndex<S, T>, _TRet>
{ {
return Enumerator<TRet,std::pair<TE,int> >([=](std::pair<TE,int> & pair)->TRet{ return Linq<LinqIndex<S, T>, _TRet>(
return transform(pair.first.nextObject(), pair.second++); {*this, 0},
}, std::make_pair(_enumerator,0)); [apply](auto &pair) {
return apply(pair.linq.next(), pair.index++);
}
);
} }
template<typename TFunc> template<typename F, typename _TRet = typename std::result_of<F(T)>::type>
LinqObj<Enumerator<decltype(get_return_type<TFunc,T,int>()),std::pair<TE,int> > > select_i(TFunc transform) const auto select(F apply) const -> Linq<LinqIndex<S, T>, _TRet>
{ {
return select_i<decltype(get_return_type<TFunc,T,int>())>(transform); return select_i([apply](T &&value, int index) { return apply(value); });
} }
template<typename TRet> template<typename TRet>
LinqObj<Enumerator<TRet,std::pair<TE,int> > > select(std::function<TRet(T)> transform) const Linq<LinqIndex<S, T>, TRet> cast() const
{ {
return select_i<TRet>([=](T a, int){return transform(a);}); return select([](T &&value) { return TRet(value); });
} }
template<typename TFunc> template<typename SS, typename TT, typename TCurrent>
LinqObj<Enumerator<decltype(get_return_type<TFunc,T>()),std::pair<TE,int> > > select(TFunc transform) const struct LinqCurrentIndexFinished {
{ Linq<SS, TT> linq;
return select<decltype(get_return_type<TFunc,T>())>(transform); TCurrent current;
} int index;
bool finished;
template<typename TRet> };
LinqObj<Enumerator<TRet,std::pair<TE,int> > > cast() const
{
return select_i<TRet>([=](T a, int){return a;});
}
template<typename TRet> template<typename F, typename _TRet = typename std::result_of<F(T,int)>::type>
LinqObj<Enumerator<T,std::pair<TE,std::set<TRet> > > > distinct(std::function<TRet(T)> transform) const auto selectMany_i(F apply) const
{ -> Linq<LinqCurrentIndexFinished<S, T, _TRet>, typename _TRet::value_type>
typedef std::pair<TE,std::set<TRet> > DataType; {
return Linq<LinqCurrentIndexFinished<S, T, _TRet>, typename _TRet::value_type>(
return Enumerator<T,DataType>([=](DataType & pair)->T{ {*this, _TRet(), 0, true},
for (;;) [apply](auto &tuple) {
{ while (true) {
T object = pair.first.nextObject(); if (tuple.finished) {
TRet key = transform(object); tuple.current = apply(tuple.linq.next(), tuple.index++);
if (pair.second.find(key) == pair.second.end()) tuple.finished = false;
{ }
pair.second.insert(key); try {
return object; return tuple.current.next();
} }
catch (LinqEndException &) {
tuple.finished = true;
}
}
} }
}, std::make_pair(_enumerator,std::set<TRet>())); );
} }
template<typename TFunc> template<typename F, typename _TRet = typename std::result_of<F(T)>::type>
LinqObj<Enumerator<T,std::pair<TE,std::set<decltype(get_return_type<TFunc,T>())> > > > distinct(TFunc transform) const auto selectMany(F apply) const
-> Linq<LinqCurrentIndexFinished<S, T, _TRet>, typename _TRet::value_type>
{ {
return distinct<decltype(get_return_type<TFunc,T>())>(transform); return selectMany_i([apply](T &&value, int index) { return apply(value); });
} }
template<typename SS, typename TT, typename TTRet2>
struct LinqUnorderedSet {
Linq<SS, TT> linq;
std::unordered_set<TTRet2> set;
};
LinqObj<Enumerator<T,std::pair<TE,std::set<T> > > > distinct() const template<typename TRet>
{ Linq<LinqUnorderedSet<S, T, TRet>, T> distinct(std::function<TRet(T)> transform) const
return distinct<T>([](T a){return a;}); {
return Linq<LinqUnorderedSet<S, T, TRet>, T>(
{*this, std::unordered_set<TRet>()},
[transform](auto &tuple) {
while (true) {
T value = tuple.linq.next();
if (tuple.set.insert(transform(value)).second) {
return value;
}
}
}
);
} }
protected: Linq<LinqUnorderedSet<S, T, T>, T> distinct() const
template<typename T, typename TRet>
class transform_comparer
{ {
public: return distinct([](T &&value) { return value; });
std::function<TRet(T)> func; }
transform_comparer(std::function<TRet(T)> func_) : func(func_) {}
bool operator()(const T & a, const T & b) const template<typename TT>
{ struct StdVectorAndIterator {
return func(a) < func(b); std::vector<TT> vec;
} typename std::vector<TT>::iterator it;
}; };
public: template<typename F>
Linq<StdVectorAndIterator<T>, T> orderBy(F transform) const
{
typedef typename std::vector<T>::iterator TIter;
template<typename TRet> std::vector<T> items = toStdVector();
LinqObj<Enumerator<T,IteratorContainerPair<typename std::multiset<T,transform_comparer<T,TRet> >::iterator, std::sort(items.begin(), items.end(), [transform](const T &a, const T &b) {
std::multiset<T,transform_comparer<T,TRet> > > > > return transform(a) < transform(b);
orderBy(std::function<TRet(T)> transform) const });
{
typedef IteratorContainerPair<typename std::multiset<T,transform_comparer<T,TRet> >::iterator,
std::multiset<T,transform_comparer<T,TRet> > > DataType;
std::multiset<T,transform_comparer<T,TRet> > objects(transform);
try
{
auto en = _enumerator;
for (;;)
objects.insert(en.nextObject());
}
catch(EnumeratorEndException &) {}
return Enumerator<T,DataType>([](DataType & pair) return Linq<StdVectorAndIterator<T>, T>(
{ {items, TIter()},
return (pair.first == pair.second.end()) [](auto &tuple) {
? throw EnumeratorEndException() : *(pair.first++); if (tuple.it == TIter()) {
}, DataType(objects, [](const std::multiset<T,transform_comparer<T,TRet> > & mset){return mset.begin();})); tuple.it = tuple.vec.begin();
}
if (tuple.it == tuple.vec.end()) {
throw LinqEndException();
}
return *(tuple.it++);
}
);
} }
template<typename TFunc> Linq<StdVectorAndIterator<T>, T> orderBy() const
LinqObj<Enumerator<T,IteratorContainerPair<typename std::multiset<T,transform_comparer<T,decltype(get_return_type<TFunc,T>())> >::iterator,
std::multiset<T,transform_comparer<T,decltype(get_return_type<TFunc,T>())> > > > >
orderBy(TFunc transform) const
{ {
return orderBy<decltype(get_return_type<TFunc,T>())>(transform); return orderBy([](T &&value) { return value; });
} }
LinqObj<Enumerator<T,IteratorContainerPair<typename std::multiset<T,transform_comparer<T,T> >::iterator, template<typename TT>
std::multiset<T,transform_comparer<T,T> > > > > orderBy() const struct StdListAndReverseIterator {
{ std::list<TT> list;
return orderBy<T>([](T a){return a;}); typename std::list<TT>::reverse_iterator it;
} };
LinqObj<Enumerator<T,IteratorContainerPair<typename std::vector<T>::const_reverse_iterator,std::vector<T> > > > reverse() const Linq<StdListAndReverseIterator<T>, T> reverse() const
{ {
typedef IteratorContainerPair<typename std::vector<T>::const_reverse_iterator,std::vector<T> > DataType; typedef typename std::list<T>::reverse_iterator TIter;
std::list<T> items = toStdList();
return Enumerator<T,DataType>([](DataType & pair) return Linq<StdListAndReverseIterator<T>, T>(
{ {items, TIter()},
return (pair.first == pair.second.crend()) [](auto &tuple) {
? throw EnumeratorEndException() : *(pair.first++); if (tuple.it == TIter()) {
}, DataType(toVector(), [](const std::vector<T> & vec){return vec.crbegin();})); tuple.it = tuple.list.rbegin();
}
if (tuple.it == tuple.list.rend()) {
throw LinqEndException();
}
return *(tuple.it++);
}
);
} }
// Aggregators // Aggregators
template<typename TRet> template<typename TRet>
TRet aggregate(TRet start, std::function<TRet(TRet,T)> accumulate) const TRet aggregate(TRet start, std::function<TRet(TRet, T)> accumulate) const
{ {
try Linq<S, T> linq = *this;
{ try {
auto en = _enumerator; while (true) {
for (;;) start = accumulate(start, linq.next());
start = accumulate(start, en.nextObject()); }
} }
catch(EnumeratorEndException &) {} catch (LinqEndException &) {}
return start; return start;
} }
template<typename TRet> template<typename F>
TRet sum(std::function<TRet(T)> transform) const auto sum(F transform) const -> typename std::result_of<F(T, T)>::type
{ {
return aggregate<TRet>(TRet(), [=](TRet accumulator, T object){ return aggregate<T>(T(), [transform](T accumulator, T &&value) {
return accumulator + transform(object); return accumulator + transform(value);
}); });
} }
template<typename TFunc> template<typename TRet = T>
decltype(get_return_type<TFunc,T>()) sum(TFunc transform) const
{
return sum<decltype(get_return_type<TFunc,T>())>(transform);
}
template<typename TRet>
TRet sum() const TRet sum() const
{ {
return sum<TRet>([](T a){return a;}); return cast<TRet>().sum();
}
T sum() const
{
return sum<T>();
} }
template<typename TRet> template<typename F>
TRet avg(std::function<TRet(T)> transform) const auto avg(F transform) const -> typename std::result_of<F(T)>::type
{ {
int count = 0; int count = 0;
return aggregate<TRet>(TRet(), [&](TRet accumulator, T object)->TRet{ T res = sum([transform, &count](T &&value) {
count++; count++;
return (accumulator*(count-1) + transform(object))/count; return transform(value);
}); });
return res / count;
} }
template<typename TFunc> template<typename TRet = T>
decltype(get_return_type<TFunc,T>()) avg(TFunc transform) const
{
return avg<decltype(get_return_type<TFunc,T>())>(transform);
}
template<typename TRet>
TRet avg() const TRet avg() const
{ {
return avg<TRet>([](T a){return a;}); return cast<TRet>().avg();
} }
T avg() const int count() const
{ {
return avg<T>(); int index = 0;
foreach([&index](T &&/**/a) { index++; });
return index;
} }
int count(std::function<bool(T)> predicate) const int count(std::function<bool(T)> predicate) const
{ {
return aggregate<int>(0, [=](int count, T a){return count + (predicate(a)?1:0);}); return where(predicate).count();
} }
int count(const T & value) const int count(const T &item) const
{ {
return count([=](T a){return a == value;}); return count([item](T &&value) { return item == value; });
}
int count() const
{
return count([](T){return true;});
} }
// Bool aggregators // Bool aggregators
bool any(std::function<bool(T)> predicate) const bool any(std::function<bool(T)> predicate) const
{ {
try Linq<S, T> linq = *this;
{ try {
auto en = _enumerator; while (true) {
for (;;) if (predicate(linq.nextObject()))
if (predicate(en.nextObject()))
return true; return true;
}
} }
catch(EnumeratorEndException &) {} catch (LinqEndException &) {}
return false; return false;
} }
bool any() const bool any() const
{ {
return any([](T a){return static_cast<bool>(a);}); return any([](T &&value) { return static_cast<bool>(value); });
} }
bool all(std::function<bool(T)> predicate) const bool all(std::function<bool(T)> predicate) const
{ {
return !any([=](T a){return !predicate(a);}); return !any([predicate](T &&value) { return !predicate(value); });
} }
bool all() const bool all() const
{ {
return all([](T a){return static_cast<bool>(a);}); return all([](T &&value) { return static_cast<bool>(value); });
} }
bool contains(const T & value) const bool contains(const T &item) const
{ {
return any([&](T a){return value == a;}); return any([&item](T &&value) { return value == item; });
} }
// Election aggregators // Election aggregators
T elect(std::function<T(T,T)> accumulate) const T elect(std::function<T(T, T)> accumulate) const
{ {
auto en = _enumerator; Linq<S, T> linq = *this;
T result = en.nextObject(); T result;
try try {
{ result = linq.next();
for (;;) while (true) {
result = accumulate(result, en.nextObject()); result = accumulate(result, linq.next());
}
} }
catch(EnumeratorEndException &) {} catch (LinqEndException &) {}
return result; return result;
}
template<typename TRet>
T max(std::function<TRet(T)> transform) const
{
return elect([=](T a, T b){return transform(a) < transform(b) ? b : a;});
} }
template<typename TFunc> template<typename F>
T max(TFunc transform) const T max(F transform) const
{ {
return max<decltype(get_return_type<TFunc,T>())>(transform); return elect([transform](const T &a, const T &b) {
return (transform(a) < transform(b)) ? b : a;
});
} }
T max() const T max() const
{ {
return max<T>([](T a){return a;}); return max([](T &&value) { return value; });
} }
template<typename TRet> template<typename F>
T min(std::function<TRet(T)> transform) const T min(F transform) const
{ {
return elect([=](T a, T b){return transform(a) < transform(b) ? a : b;}); return elect([transform](const T &a, const T &b) {
} return (transform(a) < transform(b)) ? a : b;
});
template<typename TFunc>
T min(TFunc transform) const
{
return min<decltype(get_return_type<TFunc,T>())>(transform);
} }
T min() const T min() const
{ {
return min<T>([](T a){return a;}); return min([](T &&value) { return value; });
} }
// Single object returners // Single object returners
T elementAt(int index) const T elementAt(int index) const
{ {
auto en = _enumerator; return skip(index - 1).next();
for (int i = 0; i < index; i++)
en.nextObject();
return en.nextObject();
} }
T first(std::function<bool(T)> predicate) const T first(std::function<bool(T)> predicate) const
{ {
return where(predicate)._enumerator.nextObject(); return where(predicate).next();
} }
T first() const T first() const
{ {
return first([](T){return true;}); return next();
} }
T firstOrDefault(std::function<bool(T)> predicate) T firstOrDefault(std::function<bool(T)> predicate) const
{ {
try { return first(predicate); } try {
catch(EnumeratorEndException &) { return T(); } return where(predicate).next();
}
catch (LinqEndException &) {}
return T();
} }
T firstOrDefault() const T firstOrDefault() const
{ {
try { return first(); } firstOrDefault([](T &&/*value*/) { return true; });
catch(EnumeratorEndException &) { return T(); }
} }
T last(std::function<bool(T)> predicate) const T last(std::function<bool(T)> predicate) const
{ {
auto linq = where(predicate); T res;
T object = linq._enumerator.nextObject(); foreach([&res](T &&value) {
try { for (;;) object = linq._enumerator.nextObject(); } res = value;
catch(EnumeratorEndException &) { return object; } });
return res;
} }
T last() const T last() const
{ {
return last([](T){return true;}); return last([](T &&/*value*/) { return true; });
} }
T lastOrDefault(std::function<bool(T)> predicate) const T lastOrDefault(std::function<bool(T)> predicate) const
{ {
try { return last(predicate); } try {
catch(EnumeratorEndException &) { return T(); } return last(predicate);
}
catch (LinqEndException &) {}
return T();
} }
T lastOrDefault() const T lastOrDefault() const
{ {
return lastOrDefault([](T){return true;}); return lastOrDefault([](T && /*value*/) { return true; });
} }
// Set methods // Export to containers
template<typename TE2> std::vector<T> toStdVector() const
LinqObj<Enumerator<T,std::pair<bool,std::pair<TE,TE2> > > > concat(LinqObj<TE2> rhs) const
{ {
typedef std::pair<bool,std::pair<TE,TE2> > DataType; std::vector<T> items;
foreach([&items](T &&value) {
items.push_back(value);
});
return items;
}
return Enumerator<T,DataType>([=](DataType & pair)->T{ std::list<T> toStdList() const
if (pair.first) {
return pair.second.second.nextObject(); std::list<T> items;
try { return pair.second.first.nextObject(); } foreach([&items](T &&value) {
catch(EnumeratorEndException &) items.push_back(value);
{ });
pair.first = true; return items;
return pair.second.second.nextObject();
}
}, std::make_pair(false, std::make_pair(_enumerator, rhs._enumerator)));
} }
// Export methods // Bits and bytes
private: template<typename SS, typename TT>
struct LinqBytesBitsValueIndex{
Linq<SS, TT> linq;
BytesDirection bytesDirection;
BitsDirection bitsDirection;
TT value;
int index;
};
template<typename C, typename TFunc> Linq<LinqBytesBitsValueIndex<S, T>, int> bytes(BytesDirection direction = BytesFirstToLast) const
C exportToContainer(TFunc func) const { {
C container; return Linq<LinqBytesBitsValueIndex<S, T>, int>(
try {*this, direction, BitsHighToLow, T(), sizeof(T)},
{ [](auto & tuple) {
auto en = _enumerator; if (tuple.index == sizeof(T)) {
for (;;) tuple.value = tuple.linq.next();
func(container, en.nextObject()); tuple.index = 0;
} }
catch(EnumeratorEndException &) {}
return container;
}
public: uint8_t *ptr = reinterpret_cast<uint8_t *>(&tuple.value);
std::vector<T> toVector() const int byteIndex = tuple.index;
{ if (tuple.bytesDirection == BytesLastToFirst) {
return exportToContainer<std::vector<T> >([](std::vector<T> &container, const T &value){ byteIndex = sizeof(T) - 1 - byteIndex;
container.push_back(value); }
});
}
std::list<T> toList() const tuple.index++;
{ return ptr[byteIndex];
return exportToContainer<std::list<T> >([](std::list<T> &container, const T &value){ }
container.push_back(value); );
});
} }
std::deque<T> toDeque() const template<typename TRet>
Linq<LinqBytesBitsValueIndex<S, T>, TRet> unbytes(BytesDirection direction = BytesFirstToLast) const
{ {
return exportToContainer<std::deque<T> >([](std::deque<T> &container, const T &value){ return Linq<LinqBytesBitsValueIndex<S, T>, int>(
container.push_back(value); {*this, direction, BitsHighToLow, T(), 0},
}); [](auto & tuple) {
TRet value;
uint8_t *ptr = reinterpret_cast<uint8_t *>(&value);
for (int i = 0; i < sizeof(TRet); i++) {
int byteIndex = i;
if (tuple.bytesDirection == BytesLastToFirst) {
byteIndex = sizeof(TRet) - 1 - byteIndex;
}
ptr[byteIndex] = tuple.linq.next();
}
return value;
}
);
} }
std::set<T> toSet() const Linq<LinqBytesBitsValueIndex<S, T>, int> bits(BitsDirection bitsDir = BitsHighToLow, BytesDirection bytesDir = BytesFirstToLast) const
{ {
return exportToContainer<std::set<T> >([](std::set<T> &container, const T &value){ return Linq<LinqBytesBitsValueIndex<S, T>, int>(
container.insert(value); {*this, bytesDir, bitsDir, T(), sizeof(T)},
}); [](auto & tuple) {
} if (tuple.index == sizeof(T)) {
tuple.value = tuple.linq.next();
tuple.index = 0;
}
// Custom methods uint8_t *ptr = reinterpret_cast<uint8_t *>(&tuple.value);
LinqObj<Enumerator<int,std::pair<int,std::pair<TE,T> > > > bytes(BytesDirection direction = FirstToLast) const int byteIndex = tuple.index / 8;
{ if (tuple.bytesDirection == BytesLastToFirst) {
typedef std::pair<int,std::pair<TE,T> > DataType; byteIndex = sizeof(T) - 1 - byteIndex;
}
auto pair = std::make_pair(_enumerator, T()); int bitIndex = tuple.index % 8;
pair.second = pair.first.nextObject(); if (tuple.bitsDirection == BitsHighToLow) {
bitIndex = 7 - bitIndex;
}
return Enumerator<int,DataType>([=](DataType & pair_)->int{ tuple.index++;
if ((direction == FirstToLast && pair_.first == sizeof(T)) return (ptr[byteIndex] & (1 << bitIndex)) != 0;
|| (direction == LastToFirst && pair_.first == -1)) }
{ );
pair_.first = (direction == FirstToLast) ? 0 : sizeof(T)-1;
pair_.second.second = pair_.second.first.nextObject();
}
unsigned char * ptr = reinterpret_cast<unsigned char *>(&pair_.second.second);
int value = ptr[pair_.first];
pair_.first += (direction == FirstToLast) ? 1 : -1;
return value;
}, std::make_pair((direction == FirstToLast) ? 0 : sizeof(T)-1, pair));
} }
template<typename TRet> template<typename TRet>
LinqObj<Enumerator<TRet,TE> > unbytes(BytesDirection direction = FirstToLast) const Linq<LinqBytesBitsValueIndex<S, T>, TRet> unbits(BitsDirection bitsDir = BitsHighToLow, BytesDirection bytesDir = BytesFirstToLast) const
{
return Enumerator<TRet,TE>([=](TE & en)->TRet{
TRet object;
unsigned char * ptr = reinterpret_cast<unsigned char *>(&object);
for (int i = (direction == FirstToLast) ? 0 : int(sizeof(TRet)-1);
i != ((direction == FirstToLast) ? int(sizeof(TRet)) : -1);
i += (direction == FirstToLast) ? 1 : -1)
{
ptr[i] = en.nextObject();
}
return object;
}, _enumerator);
}
LinqObj<Enumerator<int,std::pair<int,std::pair<LinqObj<Enumerator<int,std::pair<int,std::pair<TE,T> > > >,unsigned char> > > >
bits(BitsDirection direction = HighToLow, BytesDirection bytesDirection = FirstToLast) const
{ {
typedef std::pair<int,std::pair<LinqObj<Enumerator<int,std::pair<int,std::pair<TE,T> > > >,unsigned char> > DataType; return Linq<LinqBytesBitsValueIndex<S, T>, int>(
{*this, bytesDir, bitsDir, T(), 0},
[](auto & tuple) {
TRet value;
uint8_t *ptr = reinterpret_cast<uint8_t *>(&value);
auto inner = bytes(bytesDirection); for (int i = 0; i < sizeof(TRet); i++) {
return Enumerator<int,DataType>([=](DataType & pair)->int{ int byteIndex = i / 8;
if ((direction == LowToHigh && pair.first == CHAR_BIT) if (tuple.bytesDirection == BytesLastToFirst) {
|| (direction == HighToLow && pair.first == -1)) byteIndex = sizeof(TRet) - 1 - byteIndex;
{ }
pair.first = (direction == LowToHigh) ? 0 : CHAR_BIT-1;
pair.second.second = static_cast<unsigned char>(pair.second.first.nextObject());
}
int value = 1 & (pair.second.second >> (pair.first % CHAR_BIT));
pair.first += (direction == LowToHigh) ? 1 : -1;
return value;
}, std::make_pair((direction == LowToHigh) ? 0 : CHAR_BIT-1,
std::make_pair(inner, inner.nextObject())));
}
LinqObj<Enumerator<unsigned char,TE> > unbits(BitsDirection direction = HighToLow) const
{
return Enumerator<unsigned char,TE>([=](TE & en)->unsigned char{
unsigned char object = 0;
for (int i = (direction == LowToHigh) ? 0 : CHAR_BIT-1;
i != ((direction == LowToHigh) ? CHAR_BIT : -1);
i += (direction == LowToHigh) ? 1 : -1)
{
object |= (en.nextObject() << i);
}
return object;
}, _enumerator);
}
template<typename TRet> int bitIndex = i % 8;
LinqObj<Enumerator<TRet,Enumerator<unsigned char,TE> > > unbits(BitsDirection direction = HighToLow, BytesDirection bytesDirection = FirstToLast) const if (tuple.bitsDirection == BitsHighToLow) {
{ bitIndex = 7 - bitIndex;
return unbits(direction).template unbytes<TRet>(bytesDirection); }
}
template<typename TE_> ptr[byteIndex] |= (tuple.linq.next()?1:0) << bitIndex;
friend std::ostream & operator << (std::ostream & stream, LinqObj<TE_> linq); }
return value;
}
);
}
}; };
template<typename TE> template<typename S, typename T>
std::ostream & operator << (std::ostream & stream, LinqObj<TE> linq) std::ostream &operator<<(std::ostream &stream, Linq<S, T> linq)
{ {
return stream << linq._enumerator; try {
while (true) {
stream << linq.next() << ' ';
}
}
catch (LinqEndException &) {}
return stream;
} }
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// Linq Creators // Linq Creators
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
template<typename T, typename TI> template<typename T>
LinqObj<Enumerator<T,TI> > from(TI begin, TI end) Linq<std::pair<T, T>, typename std::iterator_traits<T>::value_type> from(T begin, T end)
{ {
return Enumerator<T,TI>([=](TI & iter){ return Linq<std::pair<T, T>, typename std::iterator_traits<T>::value_type>(
return (iter == end) ? throw EnumeratorEndException() : *(iter++); {begin, end},
}, begin); [](auto &pair) {
if (pair.first < pair.second) {
return *(pair.first++);
}
throw LinqEndException();
}
);
} }
template<typename T, typename TI> template<typename T>
LinqObj<Enumerator<T,std::pair<TI,int> > > from(TI begin, int length) Linq<std::pair<T, T>, T> from(T it, int n)
{ {
return Enumerator<T,std::pair<TI,int> >([=](std::pair<TI,int> & pair){ return from(it, it + n);
return (pair.second++ == length) ? throw EnumeratorEndException() : *(pair.first++);
}, std::make_pair(begin,0));
} }
template<typename T, int N> template<typename T, int N>
auto from(T (&array)[N]) Linq<std::pair<T *, T *>, T> from(T (&array)[N])
-> decltype(from<T>(array, array + N))
{ {
return from<T>(array, array + N); return from((T *) (&array), (T *) (&array) + N);
} }
template<template<class> class TV, typename TT> template<template<class> class TV, typename TT>
auto from(const TV<TT> & container) auto from(const TV<TT> & container)
-> decltype(from<TT>(std::begin(container), std::end(container))) -> decltype(from(std::begin(container), std::end(container)))
{ {
return from<TT>(std::begin(container), std::end(container)); return from(std::begin(container), std::end(container));
} }
// std::list, std::vector, std::dequeue // std::list, std::vector, std::dequeue
template<template<class,class> class TV, typename TT, typename TU> template<template<class,class> class TV, typename TT, typename TU>
auto from(const TV<TT,TU> & container) auto from(const TV<TT,TU> & container)
-> decltype(from<TT>(std::begin(container), std::end(container))) -> decltype(from(std::begin(container), std::end(container)))
{ {
return from<TT>(std::begin(container), std::end(container)); return from(std::begin(container), std::end(container));
} }
// std::set // std::set
template<template<class,class,class> class TV, typename TT, typename TS, typename TU> template<template<class,class,class> class TV, typename TT, typename TS, typename TU>
auto from(const TV<TT,TS,TU> & container) auto from(const TV<TT,TS,TU> & container)
-> decltype(from<TT>(std::begin(container), std::end(container))) -> decltype(from(std::begin(container), std::end(container)))
{ {
return from<TT>(std::begin(container), std::end(container)); return from(std::begin(container), std::end(container));
} }
// std::map // std::map
template<template<class,class,class,class> class TV, typename TK, typename TT, typename TS, typename TU> template<template<class,class,class,class> class TV, typename TK, typename TT, typename TS, typename TU>
auto from(const TV<TK,TT,TS,TU> & container) auto from(const TV<TK,TT,TS,TU> & container)
-> decltype(from<std::pair<TK, TT> >(std::begin(container), std::end(container))) -> decltype(from(std::begin(container), std::end(container)))
{ {
return from<std::pair<TK,TT> >(std::begin(container), std::end(container)); return from(std::begin(container), std::end(container));
} }
// std::array // std::array
template<template<class,size_t> class TV, typename TT, size_t TL> template<template<class,size_t> class TV, typename TT, size_t TL>
auto from(const TV<TT,TL> & container) auto from(const TV<TT,TL> & container)
-> decltype(from<TT>(std::begin(container), std::end(container))) -> decltype(from(std::begin(container), std::end(container)))
{ {
return from<TT>(std::begin(container), std::end(container)); return from(std::begin(container), std::end(container));
} }
template<typename T> template<typename T>
LinqObj<Enumerator<T,int> > repeat(T value, int count) Linq<std::pair<T, int>, T> repeat(T value, int count) {
{ return Linq<std::pair<T, int>, T>(
return Enumerator<T,int>([=](int & index){ {value, count},
return (index++ >= count) ? throw EnumeratorEndException() : value; [](auto &pair) {
},0); if (pair.second > 0) {
pair.second--;
return pair.first;
}
throw LinqEndException();
}
);
} }
template<typename T> template<typename T>
LinqObj<Enumerator<T,std::pair<bool,T> > > range(T begin, T end, T step) Linq<std::pair<std::pair<T,T>,T>,T> range(T start, T end, T step) {
{ return Linq<std::pair<std::pair<T,T>,T>,T>(
return Enumerator<T,std::pair<bool,T> >([=](std::pair<bool,T> & pair){ {{start, end}, step},
if (!(pair.second < end)) [](auto & tuple) {
throw EnumeratorEndException(); if (tuple.first.first < tuple.first.second) {
if (!pair.first) return *(tuple.first.first += tuple.second);
pair.first = true; }
else throw LinqEndException();
pair.second += step; }
return pair.second; );
}, std::make_pair(false, begin));
} }
} }
\ No newline at end of file
//
// Copyright (C) <year> <copyright holders>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#pragma once
#include <set>
#include <list>
#include <deque>
#include <string>
#include <vector>
#include <iostream>
#include <functional>
#include <climits>
namespace boolinq
{
////////////////////////////////////////////////////////////////
// Enumerator template
////////////////////////////////////////////////////////////////
class LinqEndException {};
template<typename T, typename S>
class Enumerator
{
std::function<T(S&)> _nextObject;
S _data;
public:
typedef T value_type;
Enumerator(std::function<T(S&)> nextObject, S data)
: _nextObject(nextObject)
, _data(data)
{
}
T nextObject()
{
return _nextObject(_data);
}
};
template<typename T, typename S>
std::ostream & operator << (std::ostream & stream, Enumerator<T,S> enumerator)
{
try
{
for (unsigned i = 0; true; i++) {
if (i > 0) {
stream << ' ';
}
stream << enumerator.nextObject();
}
}
catch(LinqEndException &) {}
return stream;
}
////////////////////////////////////////////////////////////////
// Iterator and Container pair
////////////////////////////////////////////////////////////////
template<typename TI, typename TC>
class IteratorContainerPair
{
std::function<TI(const TC &)> get_ti;
public:
TC second;
TI first;
IteratorContainerPair(const TC & tc, std::function<TI(const TC &)> get_ti_)
: get_ti(get_ti_)
, second(tc)
, first(get_ti(second))
{
}
IteratorContainerPair(const IteratorContainerPair<TI,TC> & pair)
: get_ti(pair.get_ti)
, second(pair.second)
, first(get_ti(second))
{
for (auto it = pair.get_ti(pair.second); it != pair.first; ++it)
first++;
}
};
////////////////////////////////////////////////////////////////
// Linq methods implementation
////////////////////////////////////////////////////////////////
enum BytesDirection
{
BytesFirstToLast,
BytesLastToFirst,
};
enum BitsDirection
{
BitsHighToLow,
BitsLowToHigh,
};
template<typename TE>
class LinqObj
{
typedef typename TE::value_type T;
template<typename TFunc, typename TArg>
static auto get_return_type(TFunc * func = NULL, TArg * arg1 = NULL)
-> decltype((*func)(*arg1));
template<typename TFunc, typename T1Arg, typename T2Arg>
static auto get_return_type(TFunc * func = NULL, T1Arg * arg1 = NULL, T2Arg * arg2 = NULL)
-> decltype((*func)(*arg1,*arg2));
public:
TE _enumerator;
typedef typename TE::value_type value_type;
LinqObj(TE enumerator)
: _enumerator(enumerator)
{
}
T nextObject()
{
return _enumerator.nextObject();
}
// Main methods
void foreach_i(std::function<void(T,int)> action) const
{
auto en = _enumerator;
int index = 0;
try
{
for (;;)
action(en.nextObject(), index++);
}
catch(LinqEndException &) {}
}
void foreach(std::function<void(T)> action) const
{
foreach_i([=](T a, int){return action(a);});
}
LinqObj<Enumerator<T,std::pair<TE,int> > > where_i(std::function<bool(T,int)> predicate) const
{
return Enumerator<T,std::pair<TE,int> >([=](std::pair<TE,int> & pair)->T{
T object;
do
object = pair.first.nextObject();
while (!predicate(object, pair.second++));
return object;
}, std::make_pair(_enumerator,0));
}
LinqObj<Enumerator<T,std::pair<TE,int> > > where(std::function<bool(T)> predicate) const
{
return where_i([=](T a, int){return predicate(a);});
}
LinqObj<Enumerator<T,std::pair<TE,int> > > take(int count) const
{
return where_i([=](T, int i){
if (i == count) {
throw LinqEndException();
}
return true;
});
}
LinqObj<Enumerator<T,std::pair<TE,int> > > takeWhile_i(std::function<bool(T,int)> predicate) const
{
return Enumerator<T,std::pair<TE,int> >([=](std::pair<TE,int> & pair)->T{
T object = pair.first.nextObject();
if (!predicate(object,pair.second++)) {
throw LinqEndException();
}
return object;
}, std::make_pair(_enumerator,0));
}
LinqObj<Enumerator<T,std::pair<TE,int> > > takeWhile(std::function<bool(T)> predicate) const
{
return takeWhile_i([=](T t,int){return predicate(t);});
}
LinqObj<Enumerator<T,std::pair<TE,int> > > skip(int count) const
{
return where_i([=](T, int i){return i >= count;});
}
LinqObj<Enumerator<T,std::pair<TE,int> > > skipWhile_i(std::function<bool(T,int)> predicate) const
{
return Enumerator<T,std::pair<TE,int> >([=](std::pair<TE,int> & pair)->T{
if (pair.second != 0) {
return pair.first.nextObject();
}
T object;
do {
object = pair.first.nextObject();
} while (predicate(object,pair.second++));
return object;
}, std::make_pair(_enumerator,0));
}
LinqObj<Enumerator<T,std::pair<TE,int> > > skipWhile(std::function<bool(T)> predicate) const
{
return skipWhile_i([=](T t, int){return predicate(t);});
}
template<typename TRet>
LinqObj<Enumerator<TRet,std::pair<TE,int> > > select_i(std::function<TRet(T,int)> transform) const
{
return Enumerator<TRet,std::pair<TE,int> >([=](std::pair<TE,int> & pair)->TRet{
return transform(pair.first.nextObject(), pair.second++);
}, std::make_pair(_enumerator,0));
}
template<typename TFunc>
LinqObj<Enumerator<decltype(get_return_type<TFunc,T,int>()),std::pair<TE,int> > > select_i(TFunc transform) const
{
return select_i<decltype(get_return_type<TFunc,T,int>())>(transform);
}
template<typename TRet>
LinqObj<Enumerator<TRet,std::pair<TE,int> > > select(std::function<TRet(T)> transform) const
{
return select_i<TRet>([=](T a, int){return transform(a);});
}
template<typename TFunc>
LinqObj<Enumerator<decltype(get_return_type<TFunc,T>()),std::pair<TE,int> > > select(TFunc transform) const
{
return select<decltype(get_return_type<TFunc,T>())>(transform);
}
template<typename TRet>
LinqObj<Enumerator<TRet,std::pair<TE,int> > > cast() const
{
return select_i<TRet>([=](T a, int){return a;});
}
template<typename TRet>
LinqObj<Enumerator<T,std::pair<TE,std::set<TRet> > > > distinct(std::function<TRet(T)> transform) const
{
typedef std::pair<TE,std::set<TRet> > DataType;
return Enumerator<T,DataType>([=](DataType & pair)->T{
for (;;) {
T object = pair.first.nextObject();
TRet key = transform(object);
if (pair.second.find(key) == pair.second.end()) {
pair.second.insert(key);
return object;
}
}
}, std::make_pair(_enumerator,std::set<TRet>()));
}
template<typename TFunc>
LinqObj<Enumerator<T,std::pair<TE,std::set<decltype(get_return_type<TFunc,T>())> > > > distinct(TFunc transform) const
{
return distinct<decltype(get_return_type<TFunc,T>())>(transform);
}
LinqObj<Enumerator<T,std::pair<TE,std::set<T> > > > distinct() const
{
return distinct<T>([](T a){return a;});
}
protected:
template<typename T, typename TRet>
class transform_comparer
{
public:
std::function<TRet(T)> func;
transform_comparer(std::function<TRet(T)> func_) : func(func_) {}
bool operator()(const T & a, const T & b) const
{
return func(a) < func(b);
}
};
public:
template<typename TRet>
LinqObj<Enumerator<T,IteratorContainerPair<typename std::multiset<T,transform_comparer<T,TRet> >::iterator,
std::multiset<T,transform_comparer<T,TRet> > > > >
orderBy(std::function<TRet(T)> transform) const
{
typedef IteratorContainerPair<typename std::multiset<T,transform_comparer<T,TRet> >::iterator,
std::multiset<T,transform_comparer<T,TRet> > > DataType;
std::multiset<T,transform_comparer<T,TRet> > objects(transform);
try
{
auto en = _enumerator;
for (;;) {
objects.insert(en.nextObject());
}
}
catch(LinqEndException &) {}
return Enumerator<T,DataType>([](DataType & pair) {
if (pair.first == pair.second.end()) {
throw LinqEndException();
}
return *(pair.first++);
}, DataType(objects, [](const std::multiset<T,transform_comparer<T,TRet> > & mset){return mset.begin();}));
}
template<typename TFunc>
LinqObj<Enumerator<T,IteratorContainerPair<typename std::multiset<T,transform_comparer<T,decltype(get_return_type<TFunc,T>())> >::iterator,
std::multiset<T,transform_comparer<T,decltype(get_return_type<TFunc,T>())> > > > >
orderBy(TFunc transform) const
{
return orderBy<decltype(get_return_type<TFunc,T>())>(transform);
}
LinqObj<Enumerator<T,IteratorContainerPair<typename std::multiset<T,transform_comparer<T,T> >::iterator,
std::multiset<T,transform_comparer<T,T> > > > > orderBy() const
{
return orderBy<T>([](T a){return a;});
}
LinqObj<Enumerator<T,IteratorContainerPair<typename std::vector<T>::const_reverse_iterator,std::vector<T> > > > reverse() const
{
typedef IteratorContainerPair<typename std::vector<T>::const_reverse_iterator,std::vector<T> > DataType;
return Enumerator<T,DataType>([](DataType & pair)
{
return (pair.first == pair.second.crend())
? throw LinqEndException() : *(pair.first++);
}, DataType(toVector(), [](const std::vector<T> & vec){return vec.crbegin();}));
}
// Aggregators
template<typename TRet>
TRet aggregate(TRet start, std::function<TRet(TRet,T)> accumulate) const
{
try
{
auto en = _enumerator;
for (;;)
start = accumulate(start, en.nextObject());
}
catch(LinqEndException &) {}
return start;
}
template<typename TRet>
TRet sum(std::function<TRet(T)> transform) const
{
return aggregate<TRet>(TRet(), [=](TRet accumulator, T object){
return accumulator + transform(object);
});
}
template<typename TFunc>
decltype(get_return_type<TFunc,T>()) sum(TFunc transform) const
{
return sum<decltype(get_return_type<TFunc,T>())>(transform);
}
template<typename TRet>
TRet sum() const
{
return sum<TRet>([](T a){return a;});
}
T sum() const
{
return sum<T>();
}
template<typename TRet>
TRet avg(std::function<TRet(T)> transform) const
{
int count = 0;
return aggregate<TRet>(TRet(), [&](TRet accumulator, T object)->TRet{
count++;
return (accumulator*(count-1) + transform(object))/count;
});
}
template<typename TFunc>
decltype(get_return_type<TFunc,T>()) avg(TFunc transform) const
{
return avg<decltype(get_return_type<TFunc,T>())>(transform);
}
template<typename TRet>
TRet avg() const
{
return avg<TRet>([](T a){return a;});
}
T avg() const
{
return avg<T>();
}
int count(std::function<bool(T)> predicate) const
{
return aggregate<int>(0, [=](int count, T a){return count + (predicate(a)?1:0);});
}
int count(const T & value) const
{
return count([=](T a){return a == value;});
}
int count() const
{
return count([](T){return true;});
}
// Bool aggregators
bool any(std::function<bool(T)> predicate) const
{
try
{
auto en = _enumerator;
for (;;)
if (predicate(en.nextObject()))
return true;
}
catch(LinqEndException &) {}
return false;
}
bool any() const
{
return any([](T a){return static_cast<bool>(a);});
}
bool all(std::function<bool(T)> predicate) const
{
return !any([=](T a){return !predicate(a);});
}
bool all() const
{
return all([](T a){return static_cast<bool>(a);});
}
bool contains(const T & value) const
{
return any([&](T a){return value == a;});
}
// Election aggregators
T elect(std::function<T(T,T)> accumulate) const
{
auto en = _enumerator;
T result = en.nextObject();
try
{
for (;;)
result = accumulate(result, en.nextObject());
}
catch(LinqEndException &) {}
return result;
}
template<typename TRet>
T max(std::function<TRet(T)> transform) const
{
return elect([=](T a, T b){return transform(a) < transform(b) ? b : a;});
}
template<typename TFunc>
T max(TFunc transform) const
{
return max<decltype(get_return_type<TFunc,T>())>(transform);
}
T max() const
{
return max<T>([](T a){return a;});
}
template<typename TRet>
T min(std::function<TRet(T)> transform) const
{
return elect([=](T a, T b){return transform(a) < transform(b) ? a : b;});
}
template<typename TFunc>
T min(TFunc transform) const
{
return min<decltype(get_return_type<TFunc,T>())>(transform);
}
T min() const
{
return min<T>([](T a){return a;});
}
// Single object returners
T elementAt(int index) const
{
auto en = _enumerator;
for (int i = 0; i < index; i++)
en.nextObject();
return en.nextObject();
}
T first(std::function<bool(T)> predicate) const
{
return where(predicate)._enumerator.nextObject();
}
T first() const
{
return first([](T){return true;});
}
T firstOrDefault(std::function<bool(T)> predicate)
{
try { return first(predicate); }
catch(LinqEndException &) { return T(); }
}
T firstOrDefault() const
{
try { return first(); }
catch(LinqEndException &) { return T(); }
}
T last(std::function<bool(T)> predicate) const
{
auto linq = where(predicate);
T object = linq._enumerator.nextObject();
try { for (;;) object = linq._enumerator.nextObject(); }
catch(LinqEndException &) { return object; }
}
T last() const
{
return last([](T){return true;});
}
T lastOrDefault(std::function<bool(T)> predicate) const
{
try { return last(predicate); }
catch(LinqEndException &) { return T(); }
}
T lastOrDefault() const
{
return lastOrDefault([](T){return true;});
}
// Set methods
template<typename TE2>
LinqObj<Enumerator<T,std::pair<bool,std::pair<TE,TE2> > > > concat(LinqObj<TE2> rhs) const
{
typedef std::pair<bool,std::pair<TE,TE2> > DataType;
return Enumerator<T,DataType>([=](DataType & pair)->T{
if (pair.first)
return pair.second.second.nextObject();
try { return pair.second.first.nextObject(); }
catch(LinqEndException &)
{
pair.first = true;
return pair.second.second.nextObject();
}
}, std::make_pair(false, std::make_pair(_enumerator, rhs._enumerator)));
}
// Export methods
private:
template<typename C, typename TFunc>
C exportToContainer(TFunc func) const {
C container;
try
{
auto en = _enumerator;
for (;;)
func(container, en.nextObject());
}
catch(LinqEndException &) {}
return container;
}
public:
std::vector<T> toVector() const
{
return exportToContainer<std::vector<T> >([](std::vector<T> &container, const T &value){
container.push_back(value);
});
}
std::list<T> toList() const
{
return exportToContainer<std::list<T> >([](std::list<T> &container, const T &value){
container.push_back(value);
});
}
std::deque<T> toDeque() const
{
return exportToContainer<std::deque<T> >([](std::deque<T> &container, const T &value){
container.push_back(value);
});
}
std::set<T> toSet() const
{
return exportToContainer<std::set<T> >([](std::set<T> &container, const T &value){
container.insert(value);
});
}
// Custom methods
LinqObj<Enumerator<int,std::pair<int,std::pair<TE,T> > > > bytes(BytesDirection direction = BytesFirstToLast) const
{
typedef std::pair<int,std::pair<TE,T> > DataType;
auto pair = std::make_pair(_enumerator, T());
pair.second = pair.first.nextObject();
return Enumerator<int,DataType>([=](DataType & pair_)->int{
if ((direction == BytesFirstToLast && pair_.first == sizeof(T))
|| (direction == BytesLastToFirst && pair_.first == -1))
{
pair_.first = (direction == BytesFirstToLast) ? 0 : sizeof(T)-1;
pair_.second.second = pair_.second.first.nextObject();
}
unsigned char * ptr = reinterpret_cast<unsigned char *>(&pair_.second.second);
int value = ptr[pair_.first];
pair_.first += (direction == BytesFirstToLast) ? 1 : -1;
return value;
}, std::make_pair((direction == BytesFirstToLast) ? 0 : sizeof(T)-1, pair));
}
template<typename TRet>
LinqObj<Enumerator<TRet,TE> > unbytes(BytesDirection direction = BytesFirstToLast) const
{
return Enumerator<TRet,TE>([=](TE & en)->TRet{
TRet object;
unsigned char * ptr = reinterpret_cast<unsigned char *>(&object);
for (int i = (direction == BytesFirstToLast) ? 0 : int(sizeof(TRet)-1);
i != ((direction == BytesFirstToLast) ? int(sizeof(TRet)) : -1);
i += (direction == BytesFirstToLast) ? 1 : -1)
{
ptr[i] = en.nextObject();
}
return object;
}, _enumerator);
}
LinqObj<Enumerator<int,std::pair<int,std::pair<LinqObj<Enumerator<int,std::pair<int,std::pair<TE,T> > > >,unsigned char> > > >
bits(BitsDirection direction = BitsHighToLow, BytesDirection bytesDirection = BytesFirstToLast) const
{
typedef std::pair<int,std::pair<LinqObj<Enumerator<int,std::pair<int,std::pair<TE,T> > > >,unsigned char> > DataType;
auto inner = bytes(bytesDirection);
return Enumerator<int,DataType>([=](DataType & pair)->int{
if ((direction == BitsLowToHigh && pair.first == CHAR_BIT)
|| (direction == BitsHighToLow && pair.first == -1))
{
pair.first = (direction == BitsLowToHigh) ? 0 : CHAR_BIT-1;
pair.second.second = static_cast<unsigned char>(pair.second.first.nextObject());
}
int value = 1 & (pair.second.second >> (pair.first % CHAR_BIT));
pair.first += (direction == BitsLowToHigh) ? 1 : -1;
return value;
}, std::make_pair((direction == BitsLowToHigh) ? 0 : CHAR_BIT-1,
std::make_pair(inner, inner.nextObject())));
}
LinqObj<Enumerator<unsigned char,TE> > unbits(BitsDirection direction = BitsHighToLow) const
{
return Enumerator<unsigned char,TE>([=](TE & en)->unsigned char{
unsigned char object = 0;
for (int i = (direction == BitsLowToHigh) ? 0 : CHAR_BIT-1;
i != ((direction == BitsLowToHigh) ? CHAR_BIT : -1);
i += (direction == BitsLowToHigh) ? 1 : -1)
{
object |= (en.nextObject() << i);
}
return object;
}, _enumerator);
}
template<typename TRet>
LinqObj<Enumerator<TRet,Enumerator<unsigned char,TE> > > unbits(BitsDirection direction = BitsHighToLow, BytesDirection bytesDirection = BytesFirstToLast) const
{
return unbits(direction).template unbytes<TRet>(bytesDirection);
}
template<typename TE_>
friend std::ostream & operator << (std::ostream & stream, LinqObj<TE_> linq);
};
template<typename TE>
std::ostream & operator << (std::ostream & stream, LinqObj<TE> linq)
{
return stream << linq._enumerator;
}
////////////////////////////////////////////////////////////////
// Linq Creators
////////////////////////////////////////////////////////////////
template<typename T, typename TI>
LinqObj<Enumerator<T,TI> > from(TI begin, TI end)
{
return Enumerator<T,TI>([=](TI & iter){
return (iter == end) ? throw LinqEndException() : *(iter++);
}, begin);
}
template<typename T, typename TI>
LinqObj<Enumerator<T,std::pair<TI,int> > > from(TI begin, int length)
{
return Enumerator<T,std::pair<TI,int> >([=](std::pair<TI,int> & pair){
return (pair.second++ == length) ? throw LinqEndException() : *(pair.first++);
}, std::make_pair(begin,0));
}
template<typename T, int N>
auto from(T (&array)[N])
-> decltype(from<T>(array, array + N))
{
return from<T>(array, array + N);
}
template<template<class> class TV, typename TT>
auto from(const TV<TT> & container)
-> decltype(from<TT>(std::begin(container), std::end(container)))
{
return from<TT>(std::begin(container), std::end(container));
}
// std::list, std::vector, std::dequeue
template<template<class,class> class TV, typename TT, typename TU>
auto from(const TV<TT,TU> & container)
-> decltype(from<TT>(std::begin(container), std::end(container)))
{
return from<TT>(std::begin(container), std::end(container));
}
// std::set
template<template<class,class,class> class TV, typename TT, typename TS, typename TU>
auto from(const TV<TT,TS,TU> & container)
-> decltype(from<TT>(std::begin(container), std::end(container)))
{
return from<TT>(std::begin(container), std::end(container));
}
// std::map
template<template<class,class,class,class> class TV, typename TK, typename TT, typename TS, typename TU>
auto from(const TV<TK,TT,TS,TU> & container)
-> decltype(from<std::pair<TK, TT> >(std::begin(container), std::end(container)))
{
return from<std::pair<TK,TT> >(std::begin(container), std::end(container));
}
// std::array
template<template<class,size_t> class TV, typename TT, size_t TL>
auto from(const TV<TT,TL> & container)
-> decltype(from<TT>(std::begin(container), std::end(container)))
{
return from<TT>(std::begin(container), std::end(container));
}
template<typename T>
LinqObj<Enumerator<T,int> > repeat(T value, int count)
{
return Enumerator<T,int>([=](int & index){
return (index++ >= count) ? throw LinqEndException() : value;
},0);
}
template<typename T>
LinqObj<Enumerator<T,std::pair<T,bool> > > range(T begin, T end, T step)
{
return Enumerator<T,std::pair<T,bool> >([=](std::pair<T,bool> & pair){
if (!(pair.first < end)) {
throw LinqEndException();
}
T result = pair.first;
std::advance(pair.first, step);
return result;
}, std::make_pair(begin, false));
}
}
...@@ -47,5 +47,5 @@ TEST(Avg, FiveStringsLen) ...@@ -47,5 +47,5 @@ TEST(Avg, FiveStringsLen)
auto rng = from(src); auto rng = from(src);
EXPECT_EQ(5, rng.avg<int>([](const std::string & str){return str.size();})); EXPECT_EQ(5, rng.avg([](const std::string & str){return str.size();}));
} }
...@@ -27,7 +27,7 @@ TEST(BitsRange, OneByteHL) ...@@ -27,7 +27,7 @@ TEST(BitsRange, OneByteHL)
int ans[] = {1,0,1,0,1,0,1,0}; int ans[] = {1,0,1,0,1,0,1,0};
auto rng = from(src); auto rng = from(src);
auto dst = rng.bits(HighToLow); auto dst = rng.bits(BitsHighToLow);
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
...@@ -38,7 +38,7 @@ TEST(BitsRange, OneByteLH) ...@@ -38,7 +38,7 @@ TEST(BitsRange, OneByteLH)
int ans[] = {0,1,0,1,0,1,0,1}; int ans[] = {0,1,0,1,0,1,0,1};
auto rng = from(src); auto rng = from(src);
auto dst = rng.bits(LowToHigh); auto dst = rng.bits(BitsLowToHigh);
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
...@@ -74,7 +74,7 @@ TEST(BitsRange, OneIntHL) ...@@ -74,7 +74,7 @@ TEST(BitsRange, OneIntHL)
}; };
auto rng = from(src); auto rng = from(src);
auto dst = rng.bits(HighToLow); auto dst = rng.bits(BitsHighToLow);
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
...@@ -91,8 +91,8 @@ TEST(BitsRange, OneIntLH) ...@@ -91,8 +91,8 @@ TEST(BitsRange, OneIntLH)
}; };
auto rng = from(src); auto rng = from(src);
auto dst = rng.bits(LowToHigh,FirstToLast); auto dst = rng.bits(BitsLowToHigh,BytesFirstToLast);
auto vvv = dst.toVector(); auto vvv = dst.toStdVector();
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
...@@ -138,7 +138,7 @@ TEST(BitsRange, IntsHL) ...@@ -138,7 +138,7 @@ TEST(BitsRange, IntsHL)
}; };
auto rng = from(src); auto rng = from(src);
auto dst = rng.bits(HighToLow); auto dst = rng.bits(BitsHighToLow);
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
...@@ -160,7 +160,7 @@ TEST(BitsRange, IntsLH) ...@@ -160,7 +160,7 @@ TEST(BitsRange, IntsLH)
}; };
auto rng = from(src); auto rng = from(src);
auto dst = rng.bits(LowToHigh); auto dst = rng.bits(BitsLowToHigh);
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
...@@ -27,7 +27,7 @@ TEST(BytesRange, OneByteFL) ...@@ -27,7 +27,7 @@ TEST(BytesRange, OneByteFL)
int ans[] = {0xAA}; int ans[] = {0xAA};
auto rng = from(src); auto rng = from(src);
auto dst = rng.bytes(FirstToLast); auto dst = rng.bytes(BytesFirstToLast);
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
...@@ -38,7 +38,7 @@ TEST(BytesRange, OneByteLF) ...@@ -38,7 +38,7 @@ TEST(BytesRange, OneByteLF)
int ans[] = {0xAA}; int ans[] = {0xAA};
auto rng = from(src); auto rng = from(src);
auto dst = rng.bytes(LastToFirst); auto dst = rng.bytes(BytesLastToFirst);
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
...@@ -62,7 +62,7 @@ TEST(BytesRange, OneIntFL) ...@@ -62,7 +62,7 @@ TEST(BytesRange, OneIntFL)
int ans[] = {0x78,0x56,0x34,0x12}; int ans[] = {0x78,0x56,0x34,0x12};
auto rng = from(src); auto rng = from(src);
auto dst = rng.bytes(FirstToLast); auto dst = rng.bytes(BytesFirstToLast);
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
...@@ -73,7 +73,7 @@ TEST(BytesRange, OneIntLF) ...@@ -73,7 +73,7 @@ TEST(BytesRange, OneIntLF)
int ans[] = {0x12,0x34,0x56,0x78}; int ans[] = {0x12,0x34,0x56,0x78};
auto rng = from(src); auto rng = from(src);
auto dst = rng.bytes(LastToFirst); auto dst = rng.bytes(BytesLastToFirst);
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
...@@ -90,7 +90,7 @@ TEST(BytesRange, IntsDefault) ...@@ -90,7 +90,7 @@ TEST(BytesRange, IntsDefault)
}; };
auto rng = from(src); auto rng = from(src);
auto dst = rng.bytes(FirstToLast); auto dst = rng.bytes(BytesFirstToLast);
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
...@@ -105,7 +105,7 @@ TEST(BytesRange, IntsFL) ...@@ -105,7 +105,7 @@ TEST(BytesRange, IntsFL)
}; };
auto rng = from(src); auto rng = from(src);
auto dst = rng.bytes(FirstToLast); auto dst = rng.bytes(BytesFirstToLast);
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
...@@ -120,7 +120,7 @@ TEST(BytesRange, IntsLF) ...@@ -120,7 +120,7 @@ TEST(BytesRange, IntsLF)
}; };
auto rng = from(src); auto rng = from(src);
auto dst = rng.bytes(LastToFirst); auto dst = rng.bytes(BytesLastToFirst);
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
...@@ -16,7 +16,7 @@ void CheckRangeEqArray(R dst, T (&ans)[N], F f) ...@@ -16,7 +16,7 @@ void CheckRangeEqArray(R dst, T (&ans)[N], F f)
for (unsigned i = 0; i < N; i++) for (unsigned i = 0; i < N; i++)
EXPECT_EQ(f(ans[i]), f(dst.nextObject())); EXPECT_EQ(f(ans[i]), f(dst.nextObject()));
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
template<typename R, typename T, unsigned N> template<typename R, typename T, unsigned N>
...@@ -25,7 +25,7 @@ void CheckRangeEqArray(R dst, T (&ans)[N]) ...@@ -25,7 +25,7 @@ void CheckRangeEqArray(R dst, T (&ans)[N])
for (unsigned i = 0; i < N; i++) for (unsigned i = 0; i < N; i++)
EXPECT_EQ(ans[i], dst.nextObject()); EXPECT_EQ(ans[i], dst.nextObject());
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
template<typename T, unsigned N> template<typename T, unsigned N>
......
...@@ -27,8 +27,8 @@ TEST(DotCall, BytesRange) ...@@ -27,8 +27,8 @@ TEST(DotCall, BytesRange)
}; };
auto dstFL1 = from(src).bytes(); auto dstFL1 = from(src).bytes();
auto dstFL2 = from(src).bytes(FirstToLast); auto dstFL2 = from(src).bytes(BytesFirstToLast);
auto dstLF1 = from(src).bytes(LastToFirst); auto dstLF1 = from(src).bytes(BytesLastToFirst);
CheckRangeEqArray(dstFL1, ansFL); CheckRangeEqArray(dstFL1, ansFL);
CheckRangeEqArray(dstFL2, ansFL); CheckRangeEqArray(dstFL2, ansFL);
...@@ -48,8 +48,8 @@ TEST(DotCall, UnbytesRange) ...@@ -48,8 +48,8 @@ TEST(DotCall, UnbytesRange)
unsigned ansLF[] = {0x78563412,0xDDCCBBAA}; unsigned ansLF[] = {0x78563412,0xDDCCBBAA};
auto dstFL1 = from(src).unbytes<unsigned>(); auto dstFL1 = from(src).unbytes<unsigned>();
auto dstFL2 = from(src).unbytes<unsigned>(FirstToLast); auto dstFL2 = from(src).unbytes<unsigned>(BytesFirstToLast);
auto dstLF1 = from(src).unbytes<unsigned>(LastToFirst); auto dstLF1 = from(src).unbytes<unsigned>(BytesLastToFirst);
CheckRangeEqArray(dstFL1, ansFL); CheckRangeEqArray(dstFL1, ansFL);
CheckRangeEqArray(dstFL2, ansFL); CheckRangeEqArray(dstFL2, ansFL);
...@@ -77,9 +77,9 @@ TEST(DotCall, BitsRangeHL) ...@@ -77,9 +77,9 @@ TEST(DotCall, BitsRangeHL)
}; };
auto dstFL1 = from(src).bits(); auto dstFL1 = from(src).bits();
auto dstFL2 = from(src).bits(HighToLow); auto dstFL2 = from(src).bits(BitsHighToLow);
auto dstFL3 = from(src).bits(HighToLow,FirstToLast); auto dstFL3 = from(src).bits(BitsHighToLow,BytesFirstToLast);
auto dstLF1 = from(src).bits(HighToLow,LastToFirst); auto dstLF1 = from(src).bits(BitsHighToLow,BytesLastToFirst);
CheckRangeEqArray(dstFL1, ansFL); CheckRangeEqArray(dstFL1, ansFL);
CheckRangeEqArray(dstFL2, ansFL); CheckRangeEqArray(dstFL2, ansFL);
...@@ -105,9 +105,9 @@ TEST(DotCall, BitsRangeLH) ...@@ -105,9 +105,9 @@ TEST(DotCall, BitsRangeLH)
1,0,1,1,1,0,1,1, 1,0,1,1,1,0,1,1,
}; };
auto dstFL1 = from(src).bits(LowToHigh); auto dstFL1 = from(src).bits(BitsLowToHigh);
auto dstFL2 = from(src).bits(LowToHigh,FirstToLast); auto dstFL2 = from(src).bits(BitsLowToHigh,BytesFirstToLast);
auto dstLF1 = from(src).bits(LowToHigh,LastToFirst); auto dstLF1 = from(src).bits(BitsLowToHigh,BytesLastToFirst);
CheckRangeEqArray(dstFL1, ansFL); CheckRangeEqArray(dstFL1, ansFL);
CheckRangeEqArray(dstFL2, ansFL); CheckRangeEqArray(dstFL2, ansFL);
...@@ -130,10 +130,10 @@ TEST(DotCall, UnbitsRangeHLFL) ...@@ -130,10 +130,10 @@ TEST(DotCall, UnbitsRangeHLFL)
unsigned ansLF_1i[] = {0xDDCCBBAA}; unsigned ansLF_1i[] = {0xDDCCBBAA};
auto dst1_4b = from(src).unbits(); auto dst1_4b = from(src).unbits();
auto dst2_4b = from(src).unbits(HighToLow); auto dst2_4b = from(src).unbits(BitsHighToLow);
auto dst1_1i = from(src).unbits<unsigned>(HighToLow); auto dst1_1i = from(src).unbits<unsigned>(BitsHighToLow);
auto dst2_1i = from(src).unbits<unsigned>(HighToLow,FirstToLast); auto dst2_1i = from(src).unbits<unsigned>(BitsHighToLow,BytesFirstToLast);
auto dst3_1i = from(src).unbits<unsigned>(HighToLow,LastToFirst); auto dst3_1i = from(src).unbits<unsigned>(BitsHighToLow,BytesLastToFirst);
CheckRangeEqArray(dst1_4b, ans_4b); CheckRangeEqArray(dst1_4b, ans_4b);
CheckRangeEqArray(dst2_4b, ans_4b); CheckRangeEqArray(dst2_4b, ans_4b);
...@@ -160,9 +160,9 @@ TEST(DotCall, UnbitsRangeHLFL) ...@@ -160,9 +160,9 @@ TEST(DotCall, UnbitsRangeHLFL)
// 1,0,1,1,1,0,1,1, // 1,0,1,1,1,0,1,1,
// }; // };
// //
// auto dstFL1 = from(src).bits<LowToHigh>(); // auto dstFL1 = from(src).bits<BitsLowToHigh>();
// auto dstFL2 = from(src).bits<LowToHigh,FirstToLast>(); // auto dstFL2 = from(src).bits<BitsLowToHigh,BytesFirstToLast>();
// auto dstLF1 = from(src).bits<LowToHigh,LastToFirst>(); // auto dstLF1 = from(src).bits<BitsLowToHigh,BytesLastToFirst>();
// //
// CheckRangeEqArray(dstFL1, ansFL); // CheckRangeEqArray(dstFL1, ansFL);
// CheckRangeEqArray(dstFL2, ansFL); // CheckRangeEqArray(dstFL2, ansFL);
......
...@@ -41,7 +41,7 @@ TEST(GroupByRange, IntsFront) ...@@ -41,7 +41,7 @@ TEST(GroupByRange, IntsFront)
CheckRangeEqArray(dst.back(), ans_0); CheckRangeEqArray(dst.back(), ans_0);
CheckRangeEqArray(dst.popFront(), ans_0); CheckRangeEqArray(dst.popFront(), ans_0);
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
TEST(GroupByRange, IntsBack) TEST(GroupByRange, IntsBack)
...@@ -73,7 +73,7 @@ TEST(GroupByRange, IntsBack) ...@@ -73,7 +73,7 @@ TEST(GroupByRange, IntsBack)
CheckRangeEqArray(dst.back(), ans_1); CheckRangeEqArray(dst.back(), ans_1);
CheckRangeEqArray(dst.popBack(), ans_1); CheckRangeEqArray(dst.popBack(), ans_1);
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
...@@ -126,7 +126,7 @@ TEST(GroupByRange, CountChildrenByAge) ...@@ -126,7 +126,7 @@ TEST(GroupByRange, CountChildrenByAge)
CheckRangeEqArray(dst.back(), ans_true); CheckRangeEqArray(dst.back(), ans_true);
CheckRangeEqArray(dst.popFront(), ans_true); CheckRangeEqArray(dst.popFront(), ans_true);
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
*/ */
...@@ -126,5 +126,5 @@ TEST(IterRange, EmptyVector) ...@@ -126,5 +126,5 @@ TEST(IterRange, EmptyVector)
auto rng = from(src); auto rng = from(src);
EXPECT_THROW(rng.nextObject(), EnumeratorEndException); EXPECT_THROW(rng.nextObject(), LinqEndException);
} }
...@@ -28,7 +28,7 @@ TEST(Linq, WhereOdd) ...@@ -28,7 +28,7 @@ TEST(Linq, WhereOdd)
EXPECT_EQ(i, rng.nextObject()); EXPECT_EQ(i, rng.nextObject());
} }
EXPECT_THROW(rng.nextObject(), EnumeratorEndException); EXPECT_THROW(rng.nextObject(), LinqEndException);
} }
TEST(Linq, WhereOdd_WhereLess) TEST(Linq, WhereOdd_WhereLess)
...@@ -51,7 +51,7 @@ TEST(Linq, WhereOdd_WhereLess) ...@@ -51,7 +51,7 @@ TEST(Linq, WhereOdd_WhereLess)
EXPECT_EQ(i, rng.nextObject()); EXPECT_EQ(i, rng.nextObject());
} }
EXPECT_THROW(rng.nextObject(), EnumeratorEndException); EXPECT_THROW(rng.nextObject(), LinqEndException);
} }
TEST(Linq, WhereLess_WhereOdd) TEST(Linq, WhereLess_WhereOdd)
...@@ -215,7 +215,7 @@ TEST(Linq, Pointer_Front) ...@@ -215,7 +215,7 @@ TEST(Linq, Pointer_Front)
EXPECT_EQ(i, dst.nextObject()); EXPECT_EQ(i, dst.nextObject());
} }
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
...@@ -232,7 +232,7 @@ TEST(Linq, Array_Front) ...@@ -232,7 +232,7 @@ TEST(Linq, Array_Front)
EXPECT_EQ(i, dst.nextObject()); EXPECT_EQ(i, dst.nextObject());
} }
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
......
...@@ -63,7 +63,7 @@ TEST(OrderByRange, NoElements) ...@@ -63,7 +63,7 @@ TEST(OrderByRange, NoElements)
auto rng = from(src); auto rng = from(src);
auto dst = rng.orderBy(); auto dst = rng.orderBy();
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
......
...@@ -50,7 +50,7 @@ TEST(SkipRange, ManyToZero) ...@@ -50,7 +50,7 @@ TEST(SkipRange, ManyToZero)
auto rng = from(src); auto rng = from(src);
auto dst = rng.skip(6); auto dst = rng.skip(6);
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
TEST(SkipRange, ManyToZeroLess) TEST(SkipRange, ManyToZeroLess)
...@@ -60,7 +60,7 @@ TEST(SkipRange, ManyToZeroLess) ...@@ -60,7 +60,7 @@ TEST(SkipRange, ManyToZeroLess)
auto rng = from(src); auto rng = from(src);
auto dst = rng.skip(10); auto dst = rng.skip(10);
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
...@@ -83,7 +83,7 @@ TEST(SkipRange, OneToZero) ...@@ -83,7 +83,7 @@ TEST(SkipRange, OneToZero)
auto rng = from(src); auto rng = from(src);
auto dst = rng.skip(1); auto dst = rng.skip(1);
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
TEST(SkipRange, OneToZeroLess) TEST(SkipRange, OneToZeroLess)
...@@ -93,7 +93,7 @@ TEST(SkipRange, OneToZeroLess) ...@@ -93,7 +93,7 @@ TEST(SkipRange, OneToZeroLess)
auto rng = from(src); auto rng = from(src);
auto dst = rng.skip(2); auto dst = rng.skip(2);
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
TEST(SkipRange, ZeroToZero) TEST(SkipRange, ZeroToZero)
...@@ -103,7 +103,7 @@ TEST(SkipRange, ZeroToZero) ...@@ -103,7 +103,7 @@ TEST(SkipRange, ZeroToZero)
auto rng = from(src); auto rng = from(src);
auto dst = rng.skip(0); auto dst = rng.skip(0);
EXPECT_THROW(rng.nextObject(), EnumeratorEndException); EXPECT_THROW(rng.nextObject(), LinqEndException);
} }
TEST(SkipRange, ZeroToZeroLess) TEST(SkipRange, ZeroToZeroLess)
...@@ -113,7 +113,7 @@ TEST(SkipRange, ZeroToZeroLess) ...@@ -113,7 +113,7 @@ TEST(SkipRange, ZeroToZeroLess)
auto rng = from(src); auto rng = from(src);
auto dst = rng.skip(2); auto dst = rng.skip(2);
EXPECT_THROW(rng.nextObject(), EnumeratorEndException); EXPECT_THROW(rng.nextObject(), LinqEndException);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
...@@ -194,7 +194,7 @@ TEST(SkipWhileRange, ManyToZero) ...@@ -194,7 +194,7 @@ TEST(SkipWhileRange, ManyToZero)
auto rng = from(src); auto rng = from(src);
auto dst = rng.skipWhile([](int it){return it > 0;}); auto dst = rng.skipWhile([](int it){return it > 0;});
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
TEST(SkipWhileRange_i, ManyToZeroeByIndex) TEST(SkipWhileRange_i, ManyToZeroeByIndex)
...@@ -204,7 +204,7 @@ TEST(SkipWhileRange_i, ManyToZeroeByIndex) ...@@ -204,7 +204,7 @@ TEST(SkipWhileRange_i, ManyToZeroeByIndex)
auto rng = from(src); auto rng = from(src);
auto dst = rng.skipWhile_i([](int /*it*/, int idx){return idx < 6;}); auto dst = rng.skipWhile_i([](int /*it*/, int idx){return idx < 6;});
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
TEST(SkipWhileRange_i, ManyToZeroByItemValue) TEST(SkipWhileRange_i, ManyToZeroByItemValue)
...@@ -214,7 +214,7 @@ TEST(SkipWhileRange_i, ManyToZeroByItemValue) ...@@ -214,7 +214,7 @@ TEST(SkipWhileRange_i, ManyToZeroByItemValue)
auto rng = from(src); auto rng = from(src);
auto dst = rng.skipWhile_i([](int it, int /*idx*/){return it > 0;}); auto dst = rng.skipWhile_i([](int it, int /*idx*/){return it > 0;});
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
TEST(SkipWhileRange_i, ManyToZeroIndexAndItemValue) TEST(SkipWhileRange_i, ManyToZeroIndexAndItemValue)
...@@ -224,7 +224,7 @@ TEST(SkipWhileRange_i, ManyToZeroIndexAndItemValue) ...@@ -224,7 +224,7 @@ TEST(SkipWhileRange_i, ManyToZeroIndexAndItemValue)
auto rng = from(src); auto rng = from(src);
auto dst = rng.skipWhile_i([](int it, int idx){return idx != it;}); auto dst = rng.skipWhile_i([](int it, int idx){return idx != it;});
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
...@@ -280,7 +280,7 @@ TEST(SkipWhileRange, OneToZero) ...@@ -280,7 +280,7 @@ TEST(SkipWhileRange, OneToZero)
auto rng = from(src); auto rng = from(src);
auto dst = rng.skipWhile([](int it){return it == 5;}); auto dst = rng.skipWhile([](int it){return it == 5;});
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
TEST(SkipWhileRange_i, OneToZeroByIndex) TEST(SkipWhileRange_i, OneToZeroByIndex)
...@@ -290,7 +290,7 @@ TEST(SkipWhileRange_i, OneToZeroByIndex) ...@@ -290,7 +290,7 @@ TEST(SkipWhileRange_i, OneToZeroByIndex)
auto rng = from(src); auto rng = from(src);
auto dst = rng.skipWhile_i([](int /*it*/, int idx){return idx < 6;}); auto dst = rng.skipWhile_i([](int /*it*/, int idx){return idx < 6;});
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
TEST(SkipWhileRange_i, OneToZeroByItemValue) TEST(SkipWhileRange_i, OneToZeroByItemValue)
...@@ -300,7 +300,7 @@ TEST(SkipWhileRange_i, OneToZeroByItemValue) ...@@ -300,7 +300,7 @@ TEST(SkipWhileRange_i, OneToZeroByItemValue)
auto rng = from(src); auto rng = from(src);
auto dst = rng.skipWhile_i([](int it, int /*idx*/){return it > 0;}); auto dst = rng.skipWhile_i([](int it, int /*idx*/){return it > 0;});
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
TEST(SkipWhileRange_i, OneToZeroIndexAndItemValue) TEST(SkipWhileRange_i, OneToZeroIndexAndItemValue)
...@@ -310,7 +310,7 @@ TEST(SkipWhileRange_i, OneToZeroIndexAndItemValue) ...@@ -310,7 +310,7 @@ TEST(SkipWhileRange_i, OneToZeroIndexAndItemValue)
auto rng = from(src); auto rng = from(src);
auto dst = rng.skipWhile_i([](int it, int idx){return idx != it;}); auto dst = rng.skipWhile_i([](int it, int idx){return idx != it;});
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
TEST(SkipWhileRange, ZeroToZero) TEST(SkipWhileRange, ZeroToZero)
...@@ -320,7 +320,7 @@ TEST(SkipWhileRange, ZeroToZero) ...@@ -320,7 +320,7 @@ TEST(SkipWhileRange, ZeroToZero)
auto rng = from(src); auto rng = from(src);
auto dst = rng.skipWhile([](int){return false;}); auto dst = rng.skipWhile([](int){return false;});
EXPECT_THROW(rng.nextObject(), EnumeratorEndException); EXPECT_THROW(rng.nextObject(), LinqEndException);
} }
TEST(SkipWhileRange_i, ZeroToZero) TEST(SkipWhileRange_i, ZeroToZero)
...@@ -330,7 +330,7 @@ TEST(SkipWhileRange_i, ZeroToZero) ...@@ -330,7 +330,7 @@ TEST(SkipWhileRange_i, ZeroToZero)
auto rng = from(src); auto rng = from(src);
auto dst = rng.skipWhile_i([](int /*it*/, int /*idx*/){return true;}); auto dst = rng.skipWhile_i([](int /*it*/, int /*idx*/){return true;});
EXPECT_THROW(rng.nextObject(), EnumeratorEndException); EXPECT_THROW(rng.nextObject(), LinqEndException);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
...@@ -61,7 +61,7 @@ TEST(TakeRange, ManyToZero) ...@@ -61,7 +61,7 @@ TEST(TakeRange, ManyToZero)
auto rng = from(src); auto rng = from(src);
auto dst = rng.take(0); auto dst = rng.take(0);
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
...@@ -95,7 +95,7 @@ TEST(TakeRange, OneToZero) ...@@ -95,7 +95,7 @@ TEST(TakeRange, OneToZero)
auto rng = from(src); auto rng = from(src);
auto dst = rng.take(0); auto dst = rng.take(0);
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
TEST(TakeRange, ZeroToZero) TEST(TakeRange, ZeroToZero)
...@@ -105,7 +105,7 @@ TEST(TakeRange, ZeroToZero) ...@@ -105,7 +105,7 @@ TEST(TakeRange, ZeroToZero)
auto rng = from(src); auto rng = from(src);
auto dst = rng.take(0); auto dst = rng.take(0);
EXPECT_THROW(rng.nextObject(), EnumeratorEndException); EXPECT_THROW(rng.nextObject(), LinqEndException);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
...@@ -193,7 +193,7 @@ TEST(TakeWhileRange, ManyToZero) ...@@ -193,7 +193,7 @@ TEST(TakeWhileRange, ManyToZero)
auto rng = from(src); auto rng = from(src);
auto dst = rng.takeWhile([](int it){return it < 0;}); auto dst = rng.takeWhile([](int it){return it < 0;});
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
TEST(TakeWhileRange_i, ManyToZeroByIndex) TEST(TakeWhileRange_i, ManyToZeroByIndex)
...@@ -203,7 +203,7 @@ TEST(TakeWhileRange_i, ManyToZeroByIndex) ...@@ -203,7 +203,7 @@ TEST(TakeWhileRange_i, ManyToZeroByIndex)
auto rng = from(src); auto rng = from(src);
auto dst = rng.takeWhile_i([](int /*it*/, int idx){return idx > 0;}); auto dst = rng.takeWhile_i([](int /*it*/, int idx){return idx > 0;});
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
TEST(TakeWhileRange_i, ManyToZeroByItemValue) TEST(TakeWhileRange_i, ManyToZeroByItemValue)
...@@ -213,7 +213,7 @@ TEST(TakeWhileRange_i, ManyToZeroByItemValue) ...@@ -213,7 +213,7 @@ TEST(TakeWhileRange_i, ManyToZeroByItemValue)
auto rng = from(src); auto rng = from(src);
auto dst = rng.takeWhile_i([](int it, int /*idx*/){return it > 2;}); auto dst = rng.takeWhile_i([](int it, int /*idx*/){return it > 2;});
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
TEST(TakeWhileRange_i, ManyToZeroByIdexAndItemValue) TEST(TakeWhileRange_i, ManyToZeroByIdexAndItemValue)
...@@ -223,7 +223,7 @@ TEST(TakeWhileRange_i, ManyToZeroByIdexAndItemValue) ...@@ -223,7 +223,7 @@ TEST(TakeWhileRange_i, ManyToZeroByIdexAndItemValue)
auto rng = from(src); auto rng = from(src);
auto dst = rng.takeWhile_i([](int it, int idx){return it < 0 || idx > 0;}); auto dst = rng.takeWhile_i([](int it, int idx){return it < 0 || idx > 0;});
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
...@@ -279,7 +279,7 @@ TEST(TakeWhileRange, OneToZero) ...@@ -279,7 +279,7 @@ TEST(TakeWhileRange, OneToZero)
auto rng = from(src); auto rng = from(src);
auto dst = rng.takeWhile([](int){return false;}); auto dst = rng.takeWhile([](int){return false;});
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
TEST(TakeWhileRange_i, OneToZeroByIndex) TEST(TakeWhileRange_i, OneToZeroByIndex)
...@@ -289,7 +289,7 @@ TEST(TakeWhileRange_i, OneToZeroByIndex) ...@@ -289,7 +289,7 @@ TEST(TakeWhileRange_i, OneToZeroByIndex)
auto rng = from(src); auto rng = from(src);
auto dst = rng.takeWhile_i([](int /*it*/, int idx){return idx > 0;}); auto dst = rng.takeWhile_i([](int /*it*/, int idx){return idx > 0;});
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
TEST(TakeWhileRange_i, OneToZeroByItemValue) TEST(TakeWhileRange_i, OneToZeroByItemValue)
...@@ -299,7 +299,7 @@ TEST(TakeWhileRange_i, OneToZeroByItemValue) ...@@ -299,7 +299,7 @@ TEST(TakeWhileRange_i, OneToZeroByItemValue)
auto rng = from(src); auto rng = from(src);
auto dst = rng.takeWhile_i([](int it, int /*idx*/){return it < 5;}); auto dst = rng.takeWhile_i([](int it, int /*idx*/){return it < 5;});
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
TEST(TakeWhileRange_i, OneToZeroByIndexAndItemValue) TEST(TakeWhileRange_i, OneToZeroByIndexAndItemValue)
...@@ -309,7 +309,7 @@ TEST(TakeWhileRange_i, OneToZeroByIndexAndItemValue) ...@@ -309,7 +309,7 @@ TEST(TakeWhileRange_i, OneToZeroByIndexAndItemValue)
auto rng = from(src); auto rng = from(src);
auto dst = rng.takeWhile_i([](int it, int idx){return idx == 0 && it > 5;}); auto dst = rng.takeWhile_i([](int it, int idx){return idx == 0 && it > 5;});
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
TEST(TakeWhileRange, ZeroToZero) TEST(TakeWhileRange, ZeroToZero)
...@@ -319,7 +319,7 @@ TEST(TakeWhileRange, ZeroToZero) ...@@ -319,7 +319,7 @@ TEST(TakeWhileRange, ZeroToZero)
auto rng = from(src); auto rng = from(src);
auto dst = rng.takeWhile([](int){return false;}); auto dst = rng.takeWhile([](int){return false;});
EXPECT_THROW(rng.nextObject(), EnumeratorEndException); EXPECT_THROW(rng.nextObject(), LinqEndException);
} }
TEST(TakeWhileRange_i, ZeroToZero) TEST(TakeWhileRange_i, ZeroToZero)
...@@ -329,7 +329,7 @@ TEST(TakeWhileRange_i, ZeroToZero) ...@@ -329,7 +329,7 @@ TEST(TakeWhileRange_i, ZeroToZero)
auto rng = from(src); auto rng = from(src);
auto dst = rng.takeWhile_i([](int /*it*/, int /*idx*/){return false;}); auto dst = rng.takeWhile_i([](int /*it*/, int /*idx*/){return false;});
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
...@@ -27,7 +27,7 @@ TEST(UnbitsRange, OneByteHL) ...@@ -27,7 +27,7 @@ TEST(UnbitsRange, OneByteHL)
int ans[] = {0xAA}; int ans[] = {0xAA};
auto rng = from(src); auto rng = from(src);
auto dst = rng.unbits(HighToLow); auto dst = rng.unbits(BitsHighToLow);
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
...@@ -38,7 +38,7 @@ TEST(UnbitsRange, OneByteLH) ...@@ -38,7 +38,7 @@ TEST(UnbitsRange, OneByteLH)
int ans[] = {0xAA}; int ans[] = {0xAA};
auto rng = from(src); auto rng = from(src);
auto dst = rng.unbits(LowToHigh); auto dst = rng.unbits(BitsLowToHigh);
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
...@@ -27,7 +27,7 @@ TEST(UnbytesRange, OneIntFL) ...@@ -27,7 +27,7 @@ TEST(UnbytesRange, OneIntFL)
unsigned ans[] = {0xDDCCBBAA}; unsigned ans[] = {0xDDCCBBAA};
auto rng = from(src); auto rng = from(src);
auto dst = rng.unbytes<unsigned>(FirstToLast); auto dst = rng.unbytes<unsigned>(BytesFirstToLast);
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
...@@ -38,7 +38,7 @@ TEST(UnbytesRange, OneIntLF) ...@@ -38,7 +38,7 @@ TEST(UnbytesRange, OneIntLF)
unsigned ans[] = {0xAABBCCDD}; unsigned ans[] = {0xAABBCCDD};
auto rng = from(src); auto rng = from(src);
auto dst = rng.unbytes<unsigned>(LastToFirst); auto dst = rng.unbytes<unsigned>(BytesLastToFirst);
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
...@@ -70,7 +70,7 @@ TEST(UnbytesRange, TwoIntsFL) ...@@ -70,7 +70,7 @@ TEST(UnbytesRange, TwoIntsFL)
unsigned ans[] = {0x12345678,0xDDCCBBAA}; unsigned ans[] = {0x12345678,0xDDCCBBAA};
auto rng = from(src); auto rng = from(src);
auto dst = rng.unbytes<unsigned>(FirstToLast); auto dst = rng.unbytes<unsigned>(BytesFirstToLast);
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
...@@ -85,7 +85,7 @@ TEST(UnbytesRange, TwoIntsLF) ...@@ -85,7 +85,7 @@ TEST(UnbytesRange, TwoIntsLF)
unsigned ans[] = {0x78563412,0xAABBCCDD}; unsigned ans[] = {0x78563412,0xAABBCCDD};
auto rng = from(src); auto rng = from(src);
auto dst = rng.unbytes<unsigned>(LastToFirst); auto dst = rng.unbytes<unsigned>(BytesLastToFirst);
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
...@@ -99,5 +99,5 @@ TEST(UnbytesRange, EmptyDefault) ...@@ -99,5 +99,5 @@ TEST(UnbytesRange, EmptyDefault)
auto rng = from(src); auto rng = from(src);
auto dst = rng.unbytes<int>(); auto dst = rng.unbytes<int>();
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
...@@ -108,7 +108,7 @@ TEST(WhereRange, ManyToZero) ...@@ -108,7 +108,7 @@ TEST(WhereRange, ManyToZero)
auto rng = from(src); auto rng = from(src);
auto dst = rng.where([](int a){return a == 5;}); auto dst = rng.where([](int a){return a == 5;});
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
TEST(WhereRange, OneToZero) TEST(WhereRange, OneToZero)
...@@ -118,7 +118,7 @@ TEST(WhereRange, OneToZero) ...@@ -118,7 +118,7 @@ TEST(WhereRange, OneToZero)
auto rng = from(src); auto rng = from(src);
auto dst = rng.where( [](int a){return a>10;}); auto dst = rng.where( [](int a){return a>10;});
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.nextObject(), LinqEndException);
} }
TEST(WhereRange, ZeroToZero) TEST(WhereRange, ZeroToZero)
...@@ -128,5 +128,5 @@ TEST(WhereRange, ZeroToZero) ...@@ -128,5 +128,5 @@ TEST(WhereRange, ZeroToZero)
auto rng = from(src); auto rng = from(src);
auto dst = rng.where( [](int a){return a>0;}); auto dst = rng.where( [](int a){return a>0;});
EXPECT_THROW(rng.nextObject(), EnumeratorEndException); EXPECT_THROW(rng.nextObject(), LinqEndException);
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment