Unverified Commit 852193d9 authored by Anton Bukov's avatar Anton Bukov Committed by GitHub

Merge pull request #26 from k06a/feature/v3

Written from scratch v3
parents a32c5293 88293fd3
...@@ -7,3 +7,5 @@ ipch ...@@ -7,3 +7,5 @@ ipch
*.suo *.suo
[Bb]uild* [Bb]uild*
nbproject nbproject
.idea
cmake-build-debug
[submodule "externals/googletest"]
path = externals/googletest
url = https://github.com/google/googletest.git
[submodule "externals/benchmark"] [submodule "externals/benchmark"]
path = externals/benchmark path = externals/benchmark
url = https://github.com/google/benchmark.git url = https://github.com/google/benchmark.git
[submodule "externals/gtest"]
path = externals/gtest
url = https://github.com/google/googletest
...@@ -22,6 +22,38 @@ matrix: ...@@ -22,6 +22,38 @@ matrix:
sources: &sources sources: &sources
- ubuntu-toolchain-r-test - ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.8 - llvm-toolchain-precise-3.8
- env: CXX=g++-6 CC=gcc-6 GCOV=gcov-6
addons:
apt:
packages:
- g++-6
sources: &sources
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.8
- env: CXX=g++-7 CC=gcc-7 GCOV=gcov-7
addons:
apt:
packages:
- g++-7
sources: &sources
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.8
- env: CXX=g++-8 CC=gcc-8 GCOV=gcov-8
addons:
apt:
packages:
- g++-8
sources: &sources
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.8
- env: CXX=g++-9 CC=gcc-9 GCOV=gcov-9
addons:
apt:
packages:
- g++-9
sources: &sources
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.8
- env: CXX=clang++-3.8 CC=clang-3.8 GCOV=gcov - env: CXX=clang++-3.8 CC=clang-3.8 GCOV=gcov
addons: addons:
apt: apt:
...@@ -46,8 +78,8 @@ script: ...@@ -46,8 +78,8 @@ script:
- mkdir build - mkdir build
- cd build - cd build
- cmake .. && make - cmake .. && make
- ./test/boolinqtest - ./test/boolinq-test
- ./benchmark/boolinqbenchmark - ./bench/boolinq-bench
after_success: after_success:
- coveralls --root .. --include include --gcov-options '\-lp' --gcov $GCOV --verbose - coveralls --root .. --include include --gcov-options '\-lp' --gcov $GCOV --verbose
# Common variables. # Common variables.
CMAKE_MINIMUM_REQUIRED (VERSION 2.8) CMAKE_MINIMUM_REQUIRED (VERSION 3.0)
PROJECT (boolinq) if (POLICY CMP0048)
SET (boolinq_VERSION_MAJOR 2) cmake_policy(SET CMP0048 NEW)
SET (boolinq_VERSION_MINOR 0) endif()
PROJECT (boolinq VERSION 3.0.0 LANGUAGES CXX)
SET (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -O0 -ggdb3 -DDEBUG") SET (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -O0 -ggdb3 -DDEBUG")
...@@ -27,10 +28,9 @@ SET_DIRECTORY_PROPERTIES (PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES ${CppCheck_REPO ...@@ -27,10 +28,9 @@ SET_DIRECTORY_PROPERTIES (PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES ${CppCheck_REPO
# Testing. # Testing.
ADD_SUBDIRECTORY (externals/gtest) ADD_SUBDIRECTORY (externals/googletest)
ADD_SUBDIRECTORY (externals/benchmark) ADD_SUBDIRECTORY (externals/benchmark)
ADD_SUBDIRECTORY (test) ADD_SUBDIRECTORY (test)
ADD_SUBDIRECTORY (benchmark) ADD_SUBDIRECTORY (bench)
ADD_DEPENDENCIES (boolinqbenchmark gtest) ADD_DEPENDENCIES ("${PROJECT_NAME}-test" gtest)
ADD_DEPENDENCIES (boolinqbenchmark gtest_main) ADD_DEPENDENCIES ("${PROJECT_NAME}-bench" benchmark)
ADD_DEPENDENCIES (boolinqbenchmark benchmark)
Copyright (C) 2013 by Anton Bukov (k06aaa@gmail.com) Copyright (C) 2019 by Anton Bukov (k06aaa@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
......
# boolinq 2.0 # boolinq 3.0
[![CI Status](https://travis-ci.org/k06a/boolinq.svg?branch=master)](https://travis-ci.org/k06a/boolinq) [![CI Status](https://travis-ci.org/k06a/boolinq.svg?branch=master)](https://travis-ci.org/k06a/boolinq)
[![Coverage Status](https://coveralls.io/repos/github/k06a/boolinq/badge.svg?branch=master)](https://coveralls.io/github/k06a/boolinq?branch=master) [![Coverage Status](https://coveralls.io/repos/github/k06a/boolinq/badge.svg?branch=master)](https://coveralls.io/github/k06a/boolinq?branch=master)
C++ single-file header-only Ranges and LINQ template library Super tiny C++11 single-file header-only LINQ template library
Just imagine LINQ support for STL/Qt collections :) Just imagine .NET Framework LINQ support for STL/Qt collections :)
Get source code here: **[boolinq.h](/include/boolinq/boolinq.h)** Get source code here: **[boolinq.h](/include/boolinq/boolinq.h)**
### How it looks like? ## Wanna demo?
#### Example with integers #### Example with integers
```c++ ```C++
int src[] = {1,2,3,4,5,6,7,8}; int src[] = {1,2,3,4,5,6,7,8};
auto dst = from(src).where( [](int a){return a%2 == 1;}) // 1,3,5,7 auto dst = from(src).where( [](int a) { return a % 2 == 1; }) // 1,3,5,7
.select([](int a){return a*2;}) // 2,6,10,14 .select([](int a) { return a * 2; }) // 2,6,10,14
.where( [](int a){return a>2 && a<12;}) // 6,10 .where( [](int a) { return a > 2 && a < 12; }) // 6,10
.toVector(); .toStdVector();
// dst type: std::vector<int> // dst type: std::vector<int>
// dst items: 6,10 // dst items: 6,10
...@@ -26,15 +26,13 @@ auto dst = from(src).where( [](int a){return a%2 == 1;}) // 1,3,5,7 ...@@ -26,15 +26,13 @@ auto dst = from(src).where( [](int a){return a%2 == 1;}) // 1,3,5,7
#### Example with structs #### Example with structs
```c++ ```C++
struct Man struct Man {
{
std::string name; std::string name;
int age; int age;
}; };
Man src[] = Man src[] = {
{
{"Kevin",14}, {"Kevin",14},
{"Anton",18}, {"Anton",18},
{"Agata",17}, {"Agata",17},
...@@ -42,10 +40,10 @@ Man src[] = ...@@ -42,10 +40,10 @@ Man src[] =
{"Layer",15}, {"Layer",15},
}; };
auto dst = from(src).where( [](const Man & man){return man.age < 18;}) auto dst = from(src).where( [](const Man & man) { return man.age < 18; })
.orderBy([](const Man & man){return man.age;}) .orderBy([](const Man & man) { return man.age; })
.select( [](const Man & man){return man.name;}) .select( [](const Man & man) { return man.name; })
.toVector(); .toStdVector();
// dst type: std::vector<std::string> // dst type: std::vector<std::string>
// dst items: "Kevin", "Layer", "Agata" // dst items: "Kevin", "Layer", "Agata"
...@@ -53,16 +51,14 @@ auto dst = from(src).where( [](const Man & man){return man.age < 18;}) ...@@ -53,16 +51,14 @@ auto dst = from(src).where( [](const Man & man){return man.age < 18;})
#### Interesting example #### Interesting example
```c++ ```C++
struct Message struct Message {
{
std::string PhoneA; std::string PhoneA;
std::string PhoneB; std::string PhoneB;
std::string Text; std::string Text;
}; };
Message messages[] = Message messages[] = {
{
{"Anton","Troll","Hello, friend!"}, {"Anton","Troll","Hello, friend!"},
{"Denis","Wride","OLOLO"}, {"Denis","Wride","OLOLO"},
{"Anton","Papay","WTF?"}, {"Anton","Papay","WTF?"},
...@@ -71,78 +67,60 @@ Message messages[] = ...@@ -71,78 +67,60 @@ Message messages[] =
}; };
int DenisUniqueContactCount = int DenisUniqueContactCount =
from(messages).where( [](const Message & msg){return msg.PhoneA == "Denis";}) from(messages).where( [](const Message & msg) { return msg.PhoneA == "Denis"; })
.distinct([](const Message & msg){return msg.PhoneB;}) .distinct([](const Message & msg) { return msg.PhoneB; })
.count(); .count();
// DenisUniqueContactCount == 2 // DenisUniqueContactCount == 2
``` ```
### Containers supported? ## Containers supported?
- C++: Native arrays, pairs of pointers - C++: Native arrays, pairs of pointers
- STL: list, stack, queue, vector, deque, set, map, any compatible .... - STL: list, stack, queue, vector, deque, set, map, any compatible ....
- Qt: QList, QVector, QSet, QMap. - Qt: QList, QVector, QSet, QMap.
### Operators supported? ## Operators supported?
#### Today:
- cast&lt;T&gt;()
- take(int)
- skip(int)
- concat(range)
- where(lambda)
- select(lambda)
- reverse()
- orderBy()
- orderBy(lambda)
- groupBy(lambda)
- distinct()
- distinct(lambda)
- for_each(lambda)
- all()
- all(lambda)
- any()
- any(lambda)
- sum()
- sum(lambda)
- avg()
- avg(lambda)
- min()
- min(lambda)
- max()
- max(lambda)
- count()
- count(lambda)
- contains(value)
- elementAt(int)
- toSet()
- toList()
- toDeque()
- toVector()
- toContainer&lt;T&gt;()
#### Custom:
- bytes()
- bytes&lt;ByteOrder&gt;()
- unbytes&lt;T&gt;()
- unbytes&lt;T,ByteOrder&gt;()
- bits()
- bits&lt;BitOrder&gt;()
- bits&lt;BitOrder,ByteOrder&gt;()
- unbits()
- unbits&lt;BitOrder&gt;()
- unbits&lt;T&gt;()
- unbits&lt;T,BitOrder&gt;()
- unbits&lt;T,BitOrder,ByteOrder&gt;()
#### Coming soon: #### Filters and reorders:
- `where(predicate)`, `where_i(predicate)`
- `take(count)`, `takeWhile(predicate)`, `takeWhile_i(predicate)`
- `skip(count)`, `skipWhile(predicate)`, `skipWhile_i(predicate)`
- `orderBy()`, `orderBy(transform)`
- `distinct()`, `distinct(transform)`
- `append(items)`, `prepend(items)`
- `concat(linq)`
- `reverse()`
- `cast<T>()`
#### Transformers:
- `select(transform)`, `select_i(transform)`
- `groupBy(transform)`
- `selectMany(transfom)`
- selectMany(lambda) #### Aggregators:
#### May be will be: - `all()`, `all(predicate)`
- `any()`, `any(lambda)`
- `sum()`, `sum<T>()`, `sum(lambda)`
- `avg()`, `avg<T>()`, `avg(lambda)`
- `min()`, `min(lambda)`
- `max()`, `max(lambda)`
- `count()`, `count(value)`, `count(predicate)`
- `contains(value)`
- `elementAt(index)`
- `toStdSet()`, `toStdList()`, `toStdDeque()`, `toStdVector()`
#### Bits and Bytes:
- `bytes<T>(ByteDirection?)`
- `unbytes<T>(ByteDirection?)`
- `bits(BitsDirection?, BytesDirection?)`
- `unbits<T = unsigned char>(BitsDirection?, BytesDirection?)`
#### Coming soon:
- gz() - gz()
- ungz() - ungz()
......
# Common variables.
#SET (CMAKE_BUILD_TYPE Release)
SET (CMAKE_CXX_STANDARD 11)
SET (CMAKE_CXX_STANDARD_REQUIRED ON)
SET (TARGET "${PROJECT_NAME}-bench" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wmissing-include-dirs -Wfloat-equal -Wshadow")
SET (TARGET "${PROJECT_NAME}-bench" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wdouble-promotion -Winit-self -Weffc++")
SET (TARGET "${PROJECT_NAME}-bench" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Woverloaded-virtual -Wsign-promo")
SET (TARGET "${PROJECT_NAME}-bench" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wvla -Winvalid-pch -Winline -Wredundant-decls")
SET (TARGET "${PROJECT_NAME}-bench" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wcast-align")
SET (TARGET "${PROJECT_NAME}-bench" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wcast-qual -Wpointer-arith")
SET (TARGET "${PROJECT_NAME}-bench" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wold-style-cast")
INCLUDE_DIRECTORIES (${PROJECT_SOURCE_DIR}/include/boolinq)
INCLUDE_DIRECTORIES (${CMAKE_BINARY_DIR}/benchmark-src/include)
INCLUDE_DIRECTORIES (${CMAKE_BINARY_DIR}/googletest-src/googletest/include)
# Benchmarks.
SET (
BoolinqBench_SOURCES
${PROJECT_SOURCE_DIR}/bench/SpeedTest.cpp
)
ADD_EXECUTABLE (
"${PROJECT_NAME}-bench"
${BoolinqBench_SOURCES}
)
TARGET_LINK_LIBRARIES (
"${PROJECT_NAME}-bench"
benchmark
gtest
)
#include <stdlib.h>
#include <math.h>
#include <benchmark/benchmark.h> #include <benchmark/benchmark.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <stdlib.h>
#include <math.h>
#include "boolinq.h" #include "boolinq.h"
...@@ -61,10 +62,8 @@ static void BM_CppCode (benchmark::State& state) ...@@ -61,10 +62,8 @@ static void BM_CppCode (benchmark::State& state)
while (state.KeepRunning () ) { while (state.KeepRunning () ) {
double sum = 0; double sum = 0;
int count = 0; int count = 0;
for (unsigned i = 0; i < vecCpp.size(); i++) for (unsigned i = 0; i < vecCpp.size(); i++) {
{ if (vecCpp[i] % 2 == 1) {
if (vecCpp[i] % 2 == 1)
{
sum += vecCpp[i]; sum += vecCpp[i];
count++; count++;
} }
...@@ -72,9 +71,11 @@ static void BM_CppCode (benchmark::State& state) ...@@ -72,9 +71,11 @@ static void BM_CppCode (benchmark::State& state)
double avgValue = sum / count; double avgValue = sum / count;
double stdSum = 0; double stdSum = 0;
for (unsigned i = 0; i < vecCpp.size(); i++) for (unsigned i = 0; i < vecCpp.size(); i++) {
if (vecCpp[i] % 2 == 1) if (vecCpp[i] % 2 == 1) {
stdSum += (vecCpp[i] - avgValue)*(vecCpp[i] - avgValue); stdSum += (vecCpp[i] - avgValue) * (vecCpp[i] - avgValue);
}
}
double stdValue = stdSum / count; double stdValue = stdSum / count;
// It's no test, instead it's avoiding skip of calculation through optimization. // It's no test, instead it's avoiding skip of calculation through optimization.
...@@ -93,10 +94,8 @@ static void BM_CppIterCode (benchmark::State& state) ...@@ -93,10 +94,8 @@ static void BM_CppIterCode (benchmark::State& state)
while (state.KeepRunning () ) { while (state.KeepRunning () ) {
double sum = 0; double sum = 0;
int count = 0; int count = 0;
for (auto it = vecCppIter.begin(); it != vecCppIter.end(); ++it) for (auto it = vecCppIter.begin(); it != vecCppIter.end(); ++it) {
{ if (*it % 2 == 1) {
if (*it % 2 == 1)
{
sum += *it; sum += *it;
count++; count++;
} }
...@@ -104,9 +103,11 @@ static void BM_CppIterCode (benchmark::State& state) ...@@ -104,9 +103,11 @@ static void BM_CppIterCode (benchmark::State& state)
double avgValue = sum / count; double avgValue = sum / count;
double stdSum = 0; double stdSum = 0;
for (auto it = vecCppIter.begin(); it != vecCppIter.end(); ++it) for (auto it = vecCppIter.begin(); it != vecCppIter.end(); ++it) {
if (*it % 2 == 1) if (*it % 2 == 1) {
stdSum += (*it - avgValue)*(*it - avgValue); stdSum += (*it - avgValue) * (*it - avgValue);
}
}
double stdValue = stdSum / count; double stdValue = stdSum / count;
// It's no test, instead it's avoiding skip of calculation through optimization. // It's no test, instead it's avoiding skip of calculation through optimization.
......
# Common variables.
SET (CMAKE_BUILD_TYPE Release)
SET (CMAKE_CXX_STANDARD 11)
SET (CMAKE_CXX_STANDARD_REQUIRED ON)
SET (TARGET boolinqbenchmark CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wmissing-include-dirs -Wfloat-equal -Wshadow")
SET (TARGET boolinqbenchmark CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wdouble-promotion -Winit-self -Weffc++")
SET (TARGET boolinqbenchmark CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Woverloaded-virtual -Wsign-promo")
SET (TARGET boolinqbenchmark CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wvla -Winvalid-pch -Winline -Wredundant-decls")
SET (TARGET boolinqbenchmark CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wcast-align")
SET (TARGET boolinqbenchmark CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wcast-qual -Wpointer-arith")
SET (TARGET boolinqbenchmark CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wold-style-cast")
INCLUDE_DIRECTORIES (${PROJECT_SOURCE_DIR}/externals/benchmark/include)
INCLUDE_DIRECTORIES (${PROJECT_SOURCE_DIR}/include/boolinq)
INCLUDE_DIRECTORIES (${PROJECT_SOURCE_DIR}/externals/gtest/include)
# Benchmarks.
SET (
BoolinqBenchmark_SOURCES
${PROJECT_SOURCE_DIR}/benchmark/SpeedTest.cpp
)
ADD_EXECUTABLE (
boolinqbenchmark
${BoolinqBenchmark_SOURCES}
)
TARGET_LINK_LIBRARIES (
boolinqbenchmark
gtest
benchmark
)
Subproject commit 354b14d1a0770da28f1725fa8409af3264de3a79 Subproject commit 090faecb454fbd6e6e17a75ef8146acb037118d4
Subproject commit 2fe3bd994b3189899d93f1d5a881e725e046fdc2
Subproject commit d225acc90bc3a8c420a9bcd1f033033c1ccd7fe0
//
// 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 <limits.h>
#include <list>
#include <deque>
#include <string>
#include <vector>
#include <iostream>
#include <functional> #include <functional>
#include <climits> #include <tuple>
namespace boolinq #include <iostream>
{ #include <iterator>
//////////////////////////////////////////////////////////////// #include <vector>
// Enumerator template #include <deque>
//////////////////////////////////////////////////////////////// #include <list>
#include <set>
#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
{
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) Linq(S storage, std::function<T(S &)> nextFunc) : nextFunc(nextFunc), storage(storage)
: _enumerator(enumerator)
{ {
} }
T nextObject() T next()
{ {
return _enumerator.nextObject(); return nextFunc(storage);
} }
// Main methods void for_each_i(std::function<void(T, int)> apply) const
void foreach_i(std::function<void(T,int)> action) const
{ {
auto en = _enumerator; Linq<S, T> linq = *this;
int index = 0; try {
try for (int i = 0; ; i++) {
{ apply(linq.next(), i);
for (;;) }
action(en.nextObject(), index++);
} }
catch(EnumeratorEndException &) {} catch (LinqEndException &) {}
} }
void foreach(std::function<void(T)> action) const void for_each(std::function<void(T)> apply) const
{ {
foreach_i([=](T a, int){return action(a);}); return for_each_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<std::tuple<Linq<S, T>, int>, 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<std::tuple<Linq<S, T>, int>, T>(
T object; std::make_tuple(*this, 0),
do [filter](std::tuple<Linq<S, T>, int> &tuple) {
object = pair.first.nextObject(); Linq<S, T> &linq = std::get<0>(tuple);
while (!predicate(object, pair.second++)); int &index = std::get<1>(tuple);
return object;
}, std::make_pair(_enumerator,0)); while (true) {
T ret = linq.next();
if (filter(ret, index++)) {
return ret;
}
}
}
);
} }
LinqObj<Enumerator<T,std::pair<TE,int> > > where(std::function<bool(T)> predicate) const Linq<std::tuple<Linq<S, T>, int>, 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<std::tuple<Linq<S, T>, int>, 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<std::tuple<Linq<S, T>, int>, 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<std::tuple<Linq<S, T>, int>, 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<std::tuple<Linq<S, T>, int>, 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 Linq<std::tuple<Linq<S, T>, int, bool>, T> skipWhile_i(std::function<bool(T, int)> predicate) const
{ {
return Enumerator<T,std::pair<TE,int> >([=](std::pair<TE,int> & pair)->T{ return Linq<std::tuple<Linq<S, T>, int, bool>, T>(
if (pair.second != 0) std::make_tuple(*this, 0, false),
return pair.first.nextObject(); [predicate](std::tuple<Linq<S, T>, int, bool> &tuple) {
Linq<S, T> &linq = std::get<0>(tuple);
int &index = std::get<1>(tuple);
bool &flag = std::get<2>(tuple);
T object; if (flag) {
do return linq.next();
object = pair.first.nextObject(); }
while (predicate(object,pair.second++)); while (true) {
T ret = linq.next();
return object; if (!predicate(ret, index++)) {
}, std::make_pair(_enumerator,0)); flag = true;
return ret;
}
}
}
);
} }
LinqObj<Enumerator<T,std::pair<TE,int> > > skipWhile(std::function<bool(T)> predicate) const Linq<std::tuple<Linq<S, T>, int, bool>, 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 ... Types>
LinqObj<Enumerator<TRet,std::pair<TE,int> > > select_i(std::function<TRet(T,int)> transform) const Linq<std::tuple<Linq<S, T>, std::vector<T>, int>, T> append(Types ... newValues) const
{ {
return Enumerator<TRet,std::pair<TE,int> >([=](std::pair<TE,int> & pair)->TRet{ return Linq<std::tuple<Linq<S, T>, std::vector<T>, int>, T>(
return transform(pair.first.nextObject(), pair.second++); std::make_tuple(*this, std::vector<T>{ newValues... }, -1),
}, std::make_pair(_enumerator,0)); [](std::tuple<Linq<S, T>, std::vector<T>, int> &tuple) {
} Linq<S, T> &linq = std::get<0>(tuple);
std::vector<T> &values = std::get<1>(tuple);
int &index = std::get<2>(tuple);
template<typename TFunc> if (index == -1) {
LinqObj<Enumerator<decltype(get_return_type<TFunc,T,int>()),std::pair<TE,int> > > select_i(TFunc transform) const try {
{ return linq.next();
return select_i<decltype(get_return_type<TFunc,T,int>())>(transform); }
} catch (LinqEndException &) {
index = 0;
}
}
template<typename TRet> if (index < values.size()) {
LinqObj<Enumerator<TRet,std::pair<TE,int> > > select(std::function<TRet(T)> transform) const return values[index++];
{ }
return select_i<TRet>([=](T a, int){return transform(a);});
throw LinqEndException();
}
);
} }
template<typename TFunc> template<typename ... Types>
LinqObj<Enumerator<decltype(get_return_type<TFunc,T>()),std::pair<TE,int> > > select(TFunc transform) const Linq<std::tuple<Linq<S, T>, std::vector<T>, int>, T> prepend(Types ... newValues) const
{ {
return select<decltype(get_return_type<TFunc,T>())>(transform); return Linq<std::tuple<Linq<S, T>, std::vector<T>, int>, T>(
std::make_tuple(*this, std::vector<T>{ newValues... }, 0),
[](std::tuple<Linq<S, T>, std::vector<T>, int> &tuple) {
Linq<S, T> &linq = std::get<0>(tuple);
std::vector<T> &values = std::get<1>(tuple);
int &index = std::get<2>(tuple);
if (index < values.size()) {
return values[index++];
}
return linq.next();
}
);
} }
template<typename TRet> template<typename F, typename _TRet = typename std::result_of<F(T, int)>::type>
LinqObj<Enumerator<TRet,std::pair<TE,int> > > cast() const Linq<std::tuple<Linq<S, T>, int>, _TRet> select_i(F apply) const
{ {
return select_i<TRet>([=](T a, int){return a;}); return Linq<std::tuple<Linq<S, T>, int>, _TRet>(
} std::make_tuple(*this, 0),
[apply](std::tuple<Linq<S, T>, int> &tuple) {
Linq<S, T> &linq = std::get<0>(tuple);
int &index = std::get<1>(tuple);
template<typename TRet> return apply(linq.next(), index++);
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> 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 Linq<std::tuple<Linq<S, T>, int>, _TRet> select(F apply) const
{ {
return distinct<decltype(get_return_type<TFunc,T>())>(transform); return select_i([apply](T value, int /*index*/) { return apply(value); });
} }
template<typename TRet>
LinqObj<Enumerator<T,std::pair<TE,std::set<T> > > > distinct() const Linq<std::tuple<Linq<S, T>, int>, TRet> cast() const
{ {
return distinct<T>([](T a){return a;}); return select_i([](T value, int /*i*/) { return TRet(value); });
} }
protected: template<typename S2, typename T2>
Linq<std::tuple<Linq<S, T>, Linq<S2, T2>, bool>, T> concat(const Linq<S2, T2> & rhs) const
template<typename T, typename TRet>
class transform_comparer
{ {
public: return Linq<std::tuple<Linq<S, T>, Linq<S2, T2>, bool>, T>(
std::function<TRet(T)> func; std::make_tuple(*this, rhs, false),
transform_comparer(std::function<TRet(T)> func_) : func(func_) {} [](std::tuple<Linq<S, T>, Linq<S2, T2>, bool> &tuple){
Linq<S, T> &first = std::get<0>(tuple);
Linq<S2, T2> &second = std::get<1>(tuple);
bool &flag = std::get<2>(tuple);
bool operator()(const T & a, const T & b) const if (!flag) {
{ try {
return func(a) < func(b); return first.next();
} }
}; catch (LinqEndException &) {}
}
return second.next();
}
);
}
template<
typename F,
typename _TRet = typename std::result_of<F(T, int)>::type,
typename _TRetVal = typename _TRet::value_type
>
Linq<std::tuple<Linq<S, T>, _TRet, int, bool>, _TRetVal> selectMany_i(F apply) const
{
return Linq<std::tuple<Linq<S, T>, _TRet, int, bool>, _TRetVal>(
std::make_tuple(*this, _TRet(), 0, true),
[apply](std::tuple<Linq<S, T>, _TRet, int, bool> &tuple) {
Linq<S, T> &linq = std::get<0>(tuple);
_TRet &current = std::get<1>(tuple);
int &index = std::get<2>(tuple);
bool &finished = std::get<3>(tuple);
while (true) {
if (finished) {
current = apply(linq.next(), index++);
finished = false;
}
try {
return current.next();
}
catch (LinqEndException &) {
finished = true;
}
}
}
);
}
template<
typename F,
typename _TRet = typename std::result_of<F(T)>::type,
typename _TRetVal = typename _TRet::value_type
>
Linq<std::tuple<Linq<S, T>, _TRet, int, bool>, _TRetVal> selectMany(F apply) const
{
return selectMany_i([apply](T value, int index) { return apply(value); });
}
template<
typename F,
typename _TKey = typename std::result_of<F(T)>::type,
typename _TValue = Linq<std::tuple<Linq<S, T>, int>, T> // where(predicate)
>
Linq<std::tuple<Linq<S, T>, Linq<S, T>, std::unordered_set<_TKey> >, std::pair<_TKey, _TValue> > groupBy(F apply) const
{
return Linq<std::tuple<Linq<S, T>, Linq<S, T>, std::unordered_set<_TKey> >, std::pair<_TKey, _TValue> >(
std::make_tuple(*this, *this, std::unordered_set<_TKey>()),
[apply](std::tuple<Linq<S, T>, Linq<S, T>, std::unordered_set<_TKey> > &tuple){
Linq<S, T> &linq = std::get<0>(tuple);
Linq<S, T> &linqCopy = std::get<1>(tuple);
std::unordered_set<_TKey> &set = std::get<2>(tuple);
_TKey key = apply(linq.next());
if (set.insert(key).second) {
return std::make_pair(key, linqCopy.where([apply, key](T v){
return apply(v) == key;
}));
}
throw LinqEndException();
}
);
}
public: template<typename F, typename _TRet = typename std::result_of<F(T)>::type>
Linq<std::tuple<Linq<S, T>, std::unordered_set<_TRet> >, T> distinct(F transform) const
{
return Linq<std::tuple<Linq<S, T>, std::unordered_set<_TRet> >, T>(
std::make_tuple(*this, std::unordered_set<_TRet>()),
[transform](std::tuple<Linq<S, T>, std::unordered_set<_TRet> > &tuple) {
Linq<S, T> &linq = std::get<0>(tuple);
std::unordered_set<_TRet> &set = std::get<1>(tuple);
template<typename TRet> while (true) {
LinqObj<Enumerator<T,IteratorContainerPair<typename std::multiset<T,transform_comparer<T,TRet> >::iterator, T value = linq.next();
std::multiset<T,transform_comparer<T,TRet> > > > > if (set.insert(transform(value)).second) {
orderBy(std::function<TRet(T)> transform) const return value;
{ }
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) Linq<std::tuple<Linq<S, T>, std::unordered_set<T> >, T> distinct() const
{ {
return (pair.first == pair.second.end()) return distinct([](T value) { return value; });
? throw EnumeratorEndException() : *(pair.first++);
}, DataType(objects, [](const std::multiset<T,transform_comparer<T,TRet> > & mset){return mset.begin();}));
} }
template<typename TFunc> template<typename F, typename _TIter = typename std::vector<T>::const_iterator>
LinqObj<Enumerator<T,IteratorContainerPair<typename std::multiset<T,transform_comparer<T,decltype(get_return_type<TFunc,T>())> >::iterator, Linq<std::tuple<std::vector<T>, _TIter, bool>, T> orderBy(F transform) const
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); std::vector<T> items = toStdVector();
std::sort(items.begin(), items.end(), [transform](const T &a, const T &b) {
return transform(a) < transform(b);
});
return Linq<std::tuple<std::vector<T>, _TIter, bool>, T>(
std::make_tuple(items, _TIter(), false),
[](std::tuple<std::vector<T>, _TIter, bool> &tuple) {
std::vector<T> &vec = std::get<0>(tuple);
_TIter &it = std::get<1>(tuple);
bool &flag = std::get<2>(tuple);
if (!flag) {
flag = true;
it = vec.cbegin();
}
if (it == vec.cend()) {
throw LinqEndException();
}
return *(it++);
}
);
} }
LinqObj<Enumerator<T,IteratorContainerPair<typename std::multiset<T,transform_comparer<T,T> >::iterator, Linq<std::tuple<std::vector<T>, typename std::vector<T>::const_iterator, bool>, T> orderBy() const
std::multiset<T,transform_comparer<T,T> > > > > orderBy() const
{ {
return orderBy<T>([](T a){return a;}); return orderBy([](T value) { return value; });
} }
LinqObj<Enumerator<T,IteratorContainerPair<typename std::vector<T>::const_reverse_iterator,std::vector<T> > > > reverse() const template<typename _TIter = typename std::list<T>::const_reverse_iterator>
Linq<std::tuple<std::list<T>, _TIter, bool>, T> reverse() const
{ {
typedef IteratorContainerPair<typename std::vector<T>::const_reverse_iterator,std::vector<T> > DataType; return Linq<std::tuple<std::list<T>, _TIter, bool>, T>(
std::make_tuple(toStdList(), _TIter(), false),
[](std::tuple<std::list<T>, _TIter, bool> &tuple) {
std::list<T> &list = std::get<0>(tuple);
_TIter &it = std::get<1>(tuple);
bool &flag = std::get<2>(tuple);
return Enumerator<T,DataType>([](DataType & pair) if (!flag) {
{ flag = true;
return (pair.first == pair.second.crend()) it = list.crbegin();
? throw EnumeratorEndException() : *(pair.first++); }
}, DataType(toVector(), [](const std::vector<T> & vec){return vec.crbegin();})); if (it == list.crend()) {
throw LinqEndException();
}
return *(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, typename _TRet = typename std::result_of<F(T)>::type>
TRet sum(std::function<TRet(T)> transform) const _TRet sum(F transform) const
{ {
return aggregate<TRet>(TRet(), [=](TRet accumulator, T object){ return aggregate<_TRet>(_TRet(), [transform](_TRet 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 sum([](T value) { return TRet(value); });
} }
T sum() const template<typename F, typename _TRet = typename std::result_of<F(T)>::type>
{ _TRet avg(F transform) const
return sum<T>();
}
template<typename TRet>
TRet avg(std::function<TRet(T)> transform) const
{ {
int count = 0; int count = 0;
return aggregate<TRet>(TRet(), [&](TRet accumulator, T object)->TRet{ _TRet 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 avg([](T value) { return TRet(value); });
} }
T avg() const int count() const
{ {
return avg<T>(); int index = 0;
for_each([&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;});
}
int count() const
{ {
return count([](T){return true;}); return count([item](T value) { return item == value; });
} }
// 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.next()))
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; T result;
T result = en.nextObject(); for_each_i([accumulate, &result](T value, int i) {
try if (i == 0) {
{ result = value;
for (;;) } else {
result = accumulate(result, en.nextObject()); result = accumulate(result, value);
} }
catch(EnumeratorEndException &) {} });
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>
T min(std::function<TRet(T)> transform) const
{
return elect([=](T a, T b){return transform(a) < transform(b) ? a : b;});
} }
template<typename TFunc> template<typename F>
T min(TFunc transform) const T min(F transform) const
{ {
return min<decltype(get_return_type<TFunc,T>())>(transform); return elect([transform](const T &a, const T &b) {
return (transform(a) < transform(b)) ? a : b;
});
} }
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).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 Linq<S, T>(*this).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(); } try {
catch(EnumeratorEndException &) { return T(); } return Linq<S, T>(*this).next();
}
catch (LinqEndException &) {}
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(); int index = -1;
try { for (;;) object = linq._enumerator.nextObject(); } where(predicate).for_each_i([&res, &index](T value, int i) {
catch(EnumeratorEndException &) { return object; } res = value;
index = i;
});
if (index == -1) {
throw LinqEndException();
}
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); } T res = T();
catch(EnumeratorEndException &) { return T(); } where(predicate).for_each([&res](T value) {
res = value;
});
return res;
} }
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;
for_each([&items](T value) {
return Enumerator<T,DataType>([=](DataType & pair)->T{ items.push_back(value);
if (pair.first) });
return pair.second.second.nextObject(); return items;
try { return pair.second.first.nextObject(); }
catch(EnumeratorEndException &)
{
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(EnumeratorEndException &) {}
return container;
} }
public: std::list<T> toStdList() const
std::vector<T> toVector() const
{ {
return exportToContainer<std::vector<T> >([](std::vector<T> &container, const T &value){ std::list<T> items;
container.push_back(value); for_each([&items](T value) {
items.push_back(value);
}); });
return items;
} }
std::list<T> toList() const std::deque<T> toStdDeque() const
{ {
return exportToContainer<std::list<T> >([](std::list<T> &container, const T &value){ std::deque<T> items;
container.push_back(value); for_each([&items](T value) {
items.push_back(value);
}); });
return items;
} }
std::deque<T> toDeque() const std::set<T> toStdSet() const
{ {
return exportToContainer<std::deque<T> >([](std::deque<T> &container, const T &value){ std::set<T> items;
container.push_back(value); for_each([&items](T value) {
items.insert(value);
}); });
return items;
} }
std::set<T> toSet() const std::unordered_set<T> toStdUnorderedSet() const
{ {
return exportToContainer<std::set<T> >([](std::set<T> &container, const T &value){ std::unordered_set<T> items;
container.insert(value); for_each([&items](T value) {
items.insert(value);
}); });
return items;
} }
// Custom methods // Bits and bytes
LinqObj<Enumerator<int,std::pair<int,std::pair<TE,T> > > > bytes(BytesDirection direction = FirstToLast) const Linq<std::tuple<Linq<S, T>, BytesDirection, T, int>, int> bytes(BytesDirection direction = BytesFirstToLast) const
{ {
typedef std::pair<int,std::pair<TE,T> > DataType; return Linq<std::tuple<Linq<S, T>, BytesDirection, T, int>, int>(
std::make_tuple(*this, direction, T(), sizeof(T)),
[](std::tuple<Linq<S, T>, BytesDirection, T, int> &tuple) {
Linq<S, T> &linq = std::get<0>(tuple);
BytesDirection &bytesDirection = std::get<1>(tuple);
T &value = std::get<2>(tuple);
int &index = std::get<3>(tuple);
auto pair = std::make_pair(_enumerator, T()); if (index == sizeof(T)) {
pair.second = pair.first.nextObject(); value = linq.next();
index = 0;
}
return Enumerator<int,DataType>([=](DataType & pair_)->int{ unsigned char *ptr = reinterpret_cast<unsigned char *>(&value);
if ((direction == FirstToLast && pair_.first == sizeof(T))
|| (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> int byteIndex = index;
LinqObj<Enumerator<TRet,TE> > unbytes(BytesDirection direction = FirstToLast) const if (bytesDirection == BytesLastToFirst) {
{ byteIndex = sizeof(T) - 1 - byteIndex;
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;
auto inner = bytes(bytesDirection); index++;
return Enumerator<int,DataType>([=](DataType & pair)->int{ return ptr[byteIndex];
if ((direction == LowToHigh && pair.first == CHAR_BIT) }
|| (direction == HighToLow && pair.first == -1)) );
{
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> template<typename TRet>
LinqObj<Enumerator<TRet,Enumerator<unsigned char,TE> > > unbits(BitsDirection direction = HighToLow, BytesDirection bytesDirection = FirstToLast) const Linq<std::tuple<Linq<S, T>, BytesDirection, int>, TRet> unbytes(BytesDirection direction = BytesFirstToLast) const
{ {
return unbits(direction).template unbytes<TRet>(bytesDirection); return Linq<std::tuple<Linq<S, T>, BytesDirection, int>, TRet>(
std::make_tuple(*this, direction, 0),
[](std::tuple<Linq<S, T>, BytesDirection, int> &tuple) {
Linq<S, T> &linq = std::get<0>(tuple);
BytesDirection &bytesDirection = std::get<1>(tuple);
int &index = std::get<2>(tuple);
TRet value;
unsigned char *ptr = reinterpret_cast<unsigned char *>(&value);
for (int i = 0; i < sizeof(TRet); i++) {
int byteIndex = i;
if (bytesDirection == BytesLastToFirst) {
byteIndex = sizeof(TRet) - 1 - byteIndex;
}
ptr[byteIndex] = linq.next();
}
return value;
}
);
}
Linq<std::tuple<Linq<S, T>, BytesDirection, BitsDirection, T, int>, int> bits(BitsDirection bitsDir = BitsHighToLow, BytesDirection bytesDir = BytesFirstToLast) const
{
return Linq<std::tuple<Linq<S, T>, BytesDirection, BitsDirection, T, int>, int>(
std::make_tuple(*this, bytesDir, bitsDir, T(), sizeof(T) * CHAR_BIT),
[](std::tuple<Linq<S, T>, BytesDirection, BitsDirection, T, int> &tuple) {
Linq<S, T> &linq = std::get<0>(tuple);
BytesDirection &bytesDirection = std::get<1>(tuple);
BitsDirection &bitsDirection = std::get<2>(tuple);
T &value = std::get<3>(tuple);
int &index = std::get<4>(tuple);
if (index == sizeof(T) * CHAR_BIT) {
value = linq.next();
index = 0;
}
unsigned char *ptr = reinterpret_cast<unsigned char *>(&value);
int byteIndex = index / CHAR_BIT;
if (bytesDirection == BytesLastToFirst) {
byteIndex = sizeof(T) - 1 - byteIndex;
}
int bitIndex = index % CHAR_BIT;
if (bitsDirection == BitsHighToLow) {
bitIndex = CHAR_BIT - 1 - bitIndex;
}
index++;
return (ptr[byteIndex] >> bitIndex) & 1;
}
);
}
template<typename TRet = unsigned char>
Linq<std::tuple<Linq<S, T>, BytesDirection, BitsDirection, int>, TRet> unbits(BitsDirection bitsDir = BitsHighToLow, BytesDirection bytesDir = BytesFirstToLast) const
{
return Linq<std::tuple<Linq<S, T>, BytesDirection, BitsDirection, int>, TRet>(
std::make_tuple(*this, bytesDir, bitsDir, 0),
[](std::tuple<Linq<S, T>, BytesDirection, BitsDirection, int> &tuple) {
Linq<S, T> &linq = std::get<0>(tuple);
BytesDirection &bytesDirection = std::get<1>(tuple);
BitsDirection &bitsDirection = std::get<2>(tuple);
int &index = std::get<3>(tuple);
TRet value = TRet();
unsigned char *ptr = reinterpret_cast<unsigned char *>(&value);
for (int i = 0; i < sizeof(TRet) * CHAR_BIT; i++) {
int byteIndex = i / CHAR_BIT;
if (bytesDirection == BytesLastToFirst) {
byteIndex = sizeof(TRet) - 1 - byteIndex;
}
int bitIndex = i % CHAR_BIT;
if (bitsDirection == BitsHighToLow) {
bitIndex = CHAR_BIT - 1 - bitIndex;
}
ptr[byteIndex] &= ~(1 << bitIndex);
ptr[byteIndex] |= bool(linq.next()) << bitIndex;
}
return value;
}
);
} }
template<typename TE_>
friend std::ostream & operator << (std::ostream & stream, LinqObj<TE_> linq);
}; };
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(const T & begin, const 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++); std::make_pair(begin, end),
}, begin); [](std::pair<T, T> &pair) {
if (pair.first == pair.second) {
throw LinqEndException();
}
return *(pair.first++);
}
);
} }
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>, typename std::iterator_traits<T>::value_type> from(const 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<const T *, const T *>, T> from(T (&array)[N])
-> decltype(from<T>(array, array + N))
{ {
return from<T>(array, array + N); return from((const T *)(&array), (const 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(container.cbegin(), container.cend()))
{ {
return from<TT>(std::begin(container), std::end(container)); return from(container.cbegin(), container.cend());
} }
// 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(container.cbegin(), container.cend()))
{ {
return from<TT>(std::begin(container), std::end(container)); return from(container.cbegin(), container.cend());
} }
// 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(container.cbegin(), container.cend()))
{ {
return from<TT>(std::begin(container), std::end(container)); return from(container.cbegin(), container.cend());
} }
// 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(container.cbegin(), container.cend()))
{ {
return from<std::pair<TK,TT> >(std::begin(container), std::end(container)); return from(container.cbegin(), container.cend());
} }
// 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(container.cbegin(), container.cend()))
{ {
return from<TT>(std::begin(container), std::end(container)); return from(container.cbegin(), container.cend());
} }
template<typename T> template<typename T>
LinqObj<Enumerator<T,int> > repeat(T value, int count) Linq<std::pair<T, int>, T> repeat(const T & value, int count) {
{ return Linq<std::pair<T, int>, T>(
return Enumerator<T,int>([=](int & index){ std::make_pair(value, count),
return (index++ >= count) ? throw EnumeratorEndException() : value; [](std::pair<T, int> &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::tuple<T, T, T>, T> range(const T & start, const T & end, const T & step) {
{ return Linq<std::tuple<T, T, T>, T>(
return Enumerator<T,std::pair<bool,T> >([=](std::pair<bool,T> & pair){ std::make_tuple(start, end, step),
if (!(pair.second < end)) [](std::tuple<T, T, T> &tuple) {
throw EnumeratorEndException(); T &start = std::get<0>(tuple);
if (!pair.first) T &end = std::get<1>(tuple);
pair.first = true; T &step = std::get<2>(tuple);
else
pair.second += step; T value = start;
return pair.second; if (value < end) {
}, std::make_pair(false, begin)); start += step;
return value;
}
throw LinqEndException();
}
);
} }
} }
\ No newline at end of file
#include <vector>
#include <string>
#include <gtest/gtest.h>
#include "CommonTests.h"
#include "boolinq.h"
using namespace boolinq;
TEST(Append, ThreePlusOne)
{
std::vector<int> src = {1,2,3};
auto rng = from(src).append(4);
int ans[] = {1,2,3,4};
CheckRangeEqArray(rng, ans);
}
TEST(Append, ThreePlusTwo)
{
std::vector<int> src = {1,2,3};
auto rng = from(src).append(4, 5);
int ans[] = {1,2,3,4,5};
CheckRangeEqArray(rng, ans);
}
TEST(Append, ZeroPlusTwo)
{
std::vector<int> src;
auto rng = from(src).append(7,8);
int ans[] = {7,8};
CheckRangeEqArray(rng, ans);
}
\ No newline at end of file
...@@ -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();}));
} }
...@@ -10,7 +10,7 @@ using namespace boolinq; ...@@ -10,7 +10,7 @@ using namespace boolinq;
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
TEST(BitsRange, OneByteDefault) TEST(Bits, OneByteDefault)
{ {
unsigned char src[] = {0xAA}; unsigned char src[] = {0xAA};
int ans[] = {1,0,1,0,1,0,1,0}; int ans[] = {1,0,1,0,1,0,1,0};
...@@ -21,31 +21,31 @@ TEST(BitsRange, OneByteDefault) ...@@ -21,31 +21,31 @@ TEST(BitsRange, OneByteDefault)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(BitsRange, OneByteHL) TEST(Bits, OneByteHL)
{ {
unsigned char src[] = {0xAA}; unsigned char src[] = {0xAA};
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);
} }
TEST(BitsRange, OneByteLH) TEST(Bits, OneByteLH)
{ {
unsigned char src[] = {0xAA}; unsigned char src[] = {0xAA};
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);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
TEST(BitsRange, OneIntDefault) TEST(Bits, OneIntDefault)
{ {
unsigned int src[] = {0x12345678}; unsigned int src[] = {0x12345678};
int ans[] = int ans[] =
...@@ -62,7 +62,7 @@ TEST(BitsRange, OneIntDefault) ...@@ -62,7 +62,7 @@ TEST(BitsRange, OneIntDefault)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(BitsRange, OneIntHL) TEST(Bits, OneIntHL)
{ {
unsigned int src[] = {0x12345678}; unsigned int src[] = {0x12345678};
int ans[] = int ans[] =
...@@ -74,12 +74,12 @@ TEST(BitsRange, OneIntHL) ...@@ -74,12 +74,12 @@ 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);
} }
TEST(BitsRange, OneIntLH) TEST(Bits, OneIntLH)
{ {
unsigned int src[] = {0x12345678}; unsigned int src[] = {0x12345678};
int ans[] = int ans[] =
...@@ -91,15 +91,15 @@ TEST(BitsRange, OneIntLH) ...@@ -91,15 +91,15 @@ 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);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
TEST(BitsRange, IntsDefault) TEST(Bits, IntsDefault)
{ {
unsigned int src[] = {0x12345678,0xAABBCCDD}; unsigned int src[] = {0x12345678,0xAABBCCDD};
int ans[] = int ans[] =
...@@ -121,7 +121,7 @@ TEST(BitsRange, IntsDefault) ...@@ -121,7 +121,7 @@ TEST(BitsRange, IntsDefault)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(BitsRange, IntsHL) TEST(Bits, IntsHL)
{ {
unsigned int src[] = {0x12345678,0xAABBCCDD}; unsigned int src[] = {0x12345678,0xAABBCCDD};
int ans[] = int ans[] =
...@@ -138,12 +138,12 @@ TEST(BitsRange, IntsHL) ...@@ -138,12 +138,12 @@ 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);
} }
TEST(BitsRange, IntsLH) TEST(Bits, IntsLH)
{ {
unsigned int src[] = {0x12345678,0xAABBCCDD}; unsigned int src[] = {0x12345678,0xAABBCCDD};
int ans[] = int 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);
} }
...@@ -10,7 +10,7 @@ using namespace boolinq; ...@@ -10,7 +10,7 @@ using namespace boolinq;
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
TEST(BytesRange, OneByteDefault) TEST(Bytes, OneByteDefault)
{ {
unsigned char src[] = {0xAA}; unsigned char src[] = {0xAA};
int ans[] = {0xAA}; int ans[] = {0xAA};
...@@ -21,31 +21,31 @@ TEST(BytesRange, OneByteDefault) ...@@ -21,31 +21,31 @@ TEST(BytesRange, OneByteDefault)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(BytesRange, OneByteFL) TEST(Bytes, OneByteFL)
{ {
unsigned char src[] = {0xAA}; unsigned char src[] = {0xAA};
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);
} }
TEST(BytesRange, OneByteLF) TEST(Bytes, OneByteLF)
{ {
unsigned char src[] = {0xAA}; unsigned char src[] = {0xAA};
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);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
TEST(BytesRange, OneIntDefault) TEST(Bytes, OneIntDefault)
{ {
int src[] = {0x12345678}; int src[] = {0x12345678};
int ans[] = {0x78,0x56,0x34,0x12}; int ans[] = {0x78,0x56,0x34,0x12};
...@@ -56,31 +56,31 @@ TEST(BytesRange, OneIntDefault) ...@@ -56,31 +56,31 @@ TEST(BytesRange, OneIntDefault)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(BytesRange, OneIntFL) TEST(Bytes, OneIntFL)
{ {
int src[] = {0x12345678}; int src[] = {0x12345678};
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);
} }
TEST(BytesRange, OneIntLF) TEST(Bytes, OneIntLF)
{ {
int src[] = {0x12345678}; int src[] = {0x12345678};
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);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
TEST(BytesRange, IntsDefault) TEST(Bytes, IntsDefault)
{ {
unsigned src[] = {0x12345678, 0xAABBCCDD}; unsigned src[] = {0x12345678, 0xAABBCCDD};
int ans[] = int ans[] =
...@@ -90,12 +90,12 @@ TEST(BytesRange, IntsDefault) ...@@ -90,12 +90,12 @@ 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);
} }
TEST(BytesRange, IntsFL) TEST(Bytes, IntsFL)
{ {
unsigned src[] = {0x12345678, 0xAABBCCDD}; unsigned src[] = {0x12345678, 0xAABBCCDD};
int ans[] = int ans[] =
...@@ -105,12 +105,12 @@ TEST(BytesRange, IntsFL) ...@@ -105,12 +105,12 @@ 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);
} }
TEST(BytesRange, IntsLF) TEST(Bytes, IntsLF)
{ {
unsigned src[] = {0x12345678, 0xAABBCCDD}; unsigned src[] = {0x12345678, 0xAABBCCDD};
int ans[] = int 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);
} }
# Common variables. # Common variables.
SET (CMAKE_CXX_STANDARD 11) SET (CMAKE_CXX_STANDARD 11)
SET (CMAKE_CXX_STANDARD_REQUIRED ON) SET (CMAKE_CXX_STANDARD_REQUIRED ON)
SET (TARGET boolinqtest CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wmissing-include-dirs -Wfloat-equal -Wshadow") SET (TARGET "${PROJECT_NAME}-test" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wmissing-include-dirs -Wfloat-equal -Wshadow")
SET (TARGET boolinqtest CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wdouble-promotion -Winit-self -Weffc++ ") SET (TARGET "${PROJECT_NAME}-test" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wdouble-promotion -Winit-self -Weffc++ ")
SET (TARGET boolinqtest CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Woverloaded-virtual -Wsign-promo") SET (TARGET "${PROJECT_NAME}-test" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Woverloaded-virtual -Wsign-promo")
SET (TARGET boolinqtest CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wvla -Winvalid-pch -Winline -Wredundant-decls") SET (TARGET "${PROJECT_NAME}-test" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wvla -Winvalid-pch -Winline -Wredundant-decls")
SET (TARGET boolinqtest CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wcast-align") SET (TARGET "${PROJECT_NAME}-test" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wcast-align")
SET (TARGET boolinqtest CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wcast-qual -Wpointer-arith") SET (TARGET "${PROJECT_NAME}-test" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wcast-qual -Wpointer-arith")
SET (TARGET boolinqtest CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wold-style-cast") SET (TARGET "${PROJECT_NAME}-test" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wold-style-cast")
SET (TARGET boolinqtest CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") SET (TARGET "${PROJECT_NAME}-test" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
SET (CMAKE_SHARED_LINKER_FLAGS "-fprofile-arcs -ftest-coverage") SET (CMAKE_SHARED_LINKER_FLAGS "-fprofile-arcs -ftest-coverage")
SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
INCLUDE_DIRECTORIES (${PROJECT_SOURCE_DIR}/include/boolinq) INCLUDE_DIRECTORIES (${PROJECT_SOURCE_DIR}/include/boolinq)
INCLUDE_DIRECTORIES (${PROJECT_SOURCE_DIR}/externals/gtest/include) INCLUDE_DIRECTORIES (${CMAKE_BINARY_DIR}/googletest-src/googletest/include)
# Unit tests. # Unit tests.
SET ( SET (
...@@ -23,47 +22,54 @@ SET ( ...@@ -23,47 +22,54 @@ SET (
${PROJECT_SOURCE_DIR}/test/AllTest.cpp ${PROJECT_SOURCE_DIR}/test/AllTest.cpp
${PROJECT_SOURCE_DIR}/test/AnyTest.cpp ${PROJECT_SOURCE_DIR}/test/AnyTest.cpp
${PROJECT_SOURCE_DIR}/test/AvgTest.cpp ${PROJECT_SOURCE_DIR}/test/AvgTest.cpp
${PROJECT_SOURCE_DIR}/test/BitsRangeTest.cpp ${PROJECT_SOURCE_DIR}/test/AppendTest.cpp
${PROJECT_SOURCE_DIR}/test/BytesRangeTest.cpp ${PROJECT_SOURCE_DIR}/test/BitsTest.cpp
${PROJECT_SOURCE_DIR}/test/ConcatRangeTest.cpp ${PROJECT_SOURCE_DIR}/test/BytesTest.cpp
${PROJECT_SOURCE_DIR}/test/ConcatTest.cpp
${PROJECT_SOURCE_DIR}/test/ContainsTest.cpp ${PROJECT_SOURCE_DIR}/test/ContainsTest.cpp
${PROJECT_SOURCE_DIR}/test/CountTest.cpp ${PROJECT_SOURCE_DIR}/test/CountTest.cpp
${PROJECT_SOURCE_DIR}/test/DistinctRangeTest.cpp ${PROJECT_SOURCE_DIR}/test/DistinctTest.cpp
${PROJECT_SOURCE_DIR}/test/DotCallTest.cpp ${PROJECT_SOURCE_DIR}/test/DotCallTest.cpp
${PROJECT_SOURCE_DIR}/test/ElementAtTest.cpp ${PROJECT_SOURCE_DIR}/test/ElementAtTest.cpp
${PROJECT_SOURCE_DIR}/test/ForeachTest.cpp ${PROJECT_SOURCE_DIR}/test/FirstTest.cpp
${PROJECT_SOURCE_DIR}/test/GroupByRangeTest.cpp ${PROJECT_SOURCE_DIR}/test/ForEachTest.cpp
${PROJECT_SOURCE_DIR}/test/IterRangeTest.cpp ${PROJECT_SOURCE_DIR}/test/GroupByTest.cpp
${PROJECT_SOURCE_DIR}/test/CtorTest.cpp
${PROJECT_SOURCE_DIR}/test/LastTest.cpp
${PROJECT_SOURCE_DIR}/test/LinqTest.cpp ${PROJECT_SOURCE_DIR}/test/LinqTest.cpp
${PROJECT_SOURCE_DIR}/test/MaxTest.cpp ${PROJECT_SOURCE_DIR}/test/MaxTest.cpp
${PROJECT_SOURCE_DIR}/test/MinTest.cpp ${PROJECT_SOURCE_DIR}/test/MinTest.cpp
${PROJECT_SOURCE_DIR}/test/OrderByRangeTest.cpp ${PROJECT_SOURCE_DIR}/test/OrderByTest.cpp
${PROJECT_SOURCE_DIR}/test/ReverseRangeTest.cpp ${PROJECT_SOURCE_DIR}/test/PrependTest.cpp
${PROJECT_SOURCE_DIR}/test/SelectRangeTest.cpp ${PROJECT_SOURCE_DIR}/test/RangeTest.cpp
${PROJECT_SOURCE_DIR}/test/SkipRangeTest.cpp ${PROJECT_SOURCE_DIR}/test/ReverseTest.cpp
${PROJECT_SOURCE_DIR}/test/SkipWhileRangeTest.cpp ${PROJECT_SOURCE_DIR}/test/SelectTest.cpp
${PROJECT_SOURCE_DIR}/test/SelectManyTest.cpp
${PROJECT_SOURCE_DIR}/test/SkipTest.cpp
${PROJECT_SOURCE_DIR}/test/SkipWhileTest.cpp
${PROJECT_SOURCE_DIR}/test/SumTest.cpp ${PROJECT_SOURCE_DIR}/test/SumTest.cpp
${PROJECT_SOURCE_DIR}/test/TakeRangeTest.cpp ${PROJECT_SOURCE_DIR}/test/TakeTest.cpp
${PROJECT_SOURCE_DIR}/test/TakeWhileRangeTest.cpp ${PROJECT_SOURCE_DIR}/test/TakeWhileTest.cpp
${PROJECT_SOURCE_DIR}/test/ToDequeTest.cpp ${PROJECT_SOURCE_DIR}/test/ToStdDequeTest.cpp
${PROJECT_SOURCE_DIR}/test/ToListTest.cpp ${PROJECT_SOURCE_DIR}/test/ToStdListTest.cpp
${PROJECT_SOURCE_DIR}/test/ToSetTest.cpp ${PROJECT_SOURCE_DIR}/test/ToStdSetTest.cpp
${PROJECT_SOURCE_DIR}/test/ToVectorTest.cpp ${PROJECT_SOURCE_DIR}/test/ToStdVectorTest.cpp
${PROJECT_SOURCE_DIR}/test/UnbitsRangeTest.cpp ${PROJECT_SOURCE_DIR}/test/UnbitsTest.cpp
${PROJECT_SOURCE_DIR}/test/UnbytesRangeTest.cpp ${PROJECT_SOURCE_DIR}/test/UnbytesTest.cpp
${PROJECT_SOURCE_DIR}/test/WhereRangeTest.cpp ${PROJECT_SOURCE_DIR}/test/WhereTest.cpp
) )
ADD_EXECUTABLE ( ADD_EXECUTABLE (
boolinqtest "${PROJECT_NAME}-test"
${BoolinqTest_SOURCES} ${BoolinqTest_SOURCES}
) )
TARGET_LINK_LIBRARIES ( TARGET_LINK_LIBRARIES (
boolinqtest "${PROJECT_NAME}-test"
gtest_main gtest_main
gtest
#gcov #gcov
) )
ENABLE_TESTING () ENABLE_TESTING ()
ADD_TEST (BoolinqTest boolinqtest) ADD_TEST (BoolinqTest "${PROJECT_NAME}-test")
# Test coverage report. # Test coverage report.
...@@ -74,7 +80,7 @@ ADD_CUSTOM_COMMAND ( ...@@ -74,7 +80,7 @@ ADD_CUSTOM_COMMAND (
COMMAND lcov -q -c -f -b . -d ${PROJECT_BINARY_DIR}/boolinq -o ${Coverage_REPORT} COMMAND lcov -q -c -f -b . -d ${PROJECT_BINARY_DIR}/boolinq -o ${Coverage_REPORT}
COMMAND lcov -e ${Coverage_REPORT} '${PROJECT_SOURCE_DIR}/boolinq/*' -o ${Coverage_REPORT} COMMAND lcov -e ${Coverage_REPORT} '${PROJECT_SOURCE_DIR}/boolinq/*' -o ${Coverage_REPORT}
COMMAND genhtml ${Coverage_REPORT} --legend --demangle-cpp -f -q -o ${Coverage_DIR} COMMAND genhtml ${Coverage_REPORT} --legend --demangle-cpp -f -q -o ${Coverage_DIR}
DEPENDS boolinqtest DEPENDS "${PROJECT_NAME}-test"
) )
ADD_CUSTOM_TARGET (coverage DEPENDS ${Coverage_REPORT}) ADD_CUSTOM_TARGET (coverage DEPENDS ${Coverage_REPORT})
# FIXME: Doesn't work correctly (require explicit call cmake when files appear). # FIXME: Doesn't work correctly (require explicit call cmake when files appear).
......
...@@ -14,18 +14,18 @@ template<typename R, typename T, unsigned N, typename F> ...@@ -14,18 +14,18 @@ template<typename R, typename T, unsigned N, typename F>
void CheckRangeEqArray(R dst, T (&ans)[N], F f) 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.next()));
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.next(), LinqEndException);
} }
template<typename R, typename T, unsigned N> template<typename R, typename T, unsigned N>
void CheckRangeEqArray(R dst, T (&ans)[N]) 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.next());
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.next(), LinqEndException);
} }
template<typename T, unsigned N> template<typename T, unsigned N>
...@@ -44,7 +44,7 @@ template<typename R, typename T, unsigned N> ...@@ -44,7 +44,7 @@ template<typename R, typename T, unsigned N>
void CheckRangeEqSet(R dst, T (&ans)[N]) void CheckRangeEqSet(R dst, T (&ans)[N])
{ {
std::set<T> expected = ArrayToSet(ans); std::set<T> expected = ArrayToSet(ans);
std::set<typename R::value_type> actual = dst.toSet(); std::set<typename R::value_type> actual = dst.toStdSet();
EXPECT_EQ(expected.size(), actual.size()); EXPECT_EQ(expected.size(), actual.size());
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
using namespace boolinq; using namespace boolinq;
TEST(ConcatRange, ArrayArray) TEST(Concat, ArrayArray)
{ {
int src1[] = {1,2,3,4,5}; int src1[] = {1,2,3,4,5};
int src2[] = {6,7,8,9}; int src2[] = {6,7,8,9};
...@@ -19,7 +19,7 @@ TEST(ConcatRange, ArrayArray) ...@@ -19,7 +19,7 @@ TEST(ConcatRange, ArrayArray)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(ConcatRange, ArrayVector) TEST(Concat, ArrayVector)
{ {
int src1[] = {1,2,3,4,5}; int src1[] = {1,2,3,4,5};
std::vector<int> src2; std::vector<int> src2;
...@@ -37,7 +37,7 @@ TEST(ConcatRange, ArrayVector) ...@@ -37,7 +37,7 @@ TEST(ConcatRange, ArrayVector)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(ConcatRange, ArrayVectorArray) TEST(Concat, ArrayVectorArray)
{ {
int src1[] = {1,2,3,4,5}; int src1[] = {1,2,3,4,5};
std::vector<int> src2; std::vector<int> src2;
......
...@@ -15,7 +15,7 @@ using namespace boolinq; ...@@ -15,7 +15,7 @@ using namespace boolinq;
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
TEST(IterRange, ListInt) TEST(Ctor, ListInt)
{ {
std::list<int> lst; std::list<int> lst;
lst.push_back(1); lst.push_back(1);
...@@ -27,11 +27,11 @@ TEST(IterRange, ListInt) ...@@ -27,11 +27,11 @@ TEST(IterRange, ListInt)
int ans[] = {1,2,3,4,5}; int ans[] = {1,2,3,4,5};
CheckRangeEqArray(from(lst), ans); CheckRangeEqArray(from(lst), ans);
CheckRangeEqArray(from<int>(lst.begin(), lst.end()), ans); CheckRangeEqArray(from(lst.begin(), lst.end()), ans);
CheckRangeEqArray(from<int>(lst.cbegin(), lst.cend()), ans); CheckRangeEqArray(from(lst.cbegin(), lst.cend()), ans);
} }
TEST(IterRange, DequeInt) TEST(Ctor, DequeInt)
{ {
std::deque<int> dck; std::deque<int> dck;
dck.push_back(1); dck.push_back(1);
...@@ -43,11 +43,11 @@ TEST(IterRange, DequeInt) ...@@ -43,11 +43,11 @@ TEST(IterRange, DequeInt)
int ans[] = {1,2,3,4,5}; int ans[] = {1,2,3,4,5};
CheckRangeEqArray(from(dck), ans); CheckRangeEqArray(from(dck), ans);
CheckRangeEqArray(from<int>(dck.begin(), dck.end()), ans); CheckRangeEqArray(from(dck.begin(), dck.end()), ans);
CheckRangeEqArray(from<int>(dck.cbegin(), dck.cend()), ans); CheckRangeEqArray(from(dck.cbegin(), dck.cend()), ans);
} }
TEST(IterRange, VectorInt) TEST(Ctor, VectorInt)
{ {
std::vector<int> vec; std::vector<int> vec;
vec.push_back(1); vec.push_back(1);
...@@ -59,44 +59,44 @@ TEST(IterRange, VectorInt) ...@@ -59,44 +59,44 @@ TEST(IterRange, VectorInt)
int ans[] = {1,2,3,4,5}; int ans[] = {1,2,3,4,5};
CheckRangeEqArray(from(vec), ans); CheckRangeEqArray(from(vec), ans);
CheckRangeEqArray(from<int>(vec.begin(), vec.end()), ans); CheckRangeEqArray(from(vec.begin(), vec.end()), ans);
CheckRangeEqArray(from<int>(vec.cbegin(), vec.cend()), ans); CheckRangeEqArray(from(vec.cbegin(), vec.cend()), ans);
} }
TEST(IterRange, SetInt) TEST(Ctor, SetInt)
{ {
std::set<int> set = {1,2,3,4,5}; std::set<int> set = {1,2,3,4,5};
int ans[] = {1,2,3,4,5}; int ans[] = {1,2,3,4,5};
CheckRangeEqSet(from(set), ans); CheckRangeEqSet(from(set), ans);
CheckRangeEqSet(from<int>(set.begin(), set.end()), ans); CheckRangeEqSet(from(set.begin(), set.end()), ans);
CheckRangeEqSet(from<int>(set.cbegin(), set.cend()), ans); CheckRangeEqSet(from(set.cbegin(), set.cend()), ans);
} }
TEST(IterRange, MapInt) //TEST(Ctor, MapInt)
{ //{
std::map<int, int> map = {{5,1},{4,2},{3,3},{2,4},{1,5}}; // std::map<int, int> map = {{5,1},{4,2},{3,3},{2,4},{1,5}};
std::pair<int, int> ans[] = {{5,1},{4,2},{3,3},{2,4},{1,5}}; // std::pair<int, int> ans[] = {{5,1},{4,2},{3,3},{2,4},{1,5}};
//
CheckRangeEqArray(from(map) // CheckRangeEqArray(from(map)
.orderBy([](std::pair<int,int> p){ return p.second; }), ans); // .orderBy([](std::pair<int,int> p){ return p.second; }), ans);
CheckRangeEqArray(from<std::pair<int,int> >(map.begin(), map.end()) // CheckRangeEqArray(from(map.begin(), map.end())
.orderBy([](std::pair<int,int> p){ return p.second; }), ans); // .orderBy([](std::pair<int,int> p){ return p.second; }), ans);
CheckRangeEqArray(from<std::pair<int,int> >(map.cbegin(), map.cend()) // CheckRangeEqArray(from(map.cbegin(), map.cend())
.orderBy([](std::pair<int,int> p){ return p.second; }), ans); // .orderBy([](std::pair<int,int> p){ return p.second; }), ans);
} //}
TEST(IterRange, StdArrayInt) TEST(Ctor, StdArrayInt)
{ {
std::array<int, 5> arr = { {1,2,3,4,5} }; std::array<int, 5> arr = { {1,2,3,4,5} };
int ans[] = {1,2,3,4,5}; int ans[] = {1,2,3,4,5};
CheckRangeEqArray(from(arr), ans); CheckRangeEqArray(from(arr), ans);
CheckRangeEqArray(from<int>(arr.begin(), arr.end()), ans); CheckRangeEqArray(from(arr.begin(), arr.end()), ans);
CheckRangeEqArray(from<int>(arr.cbegin(), arr.cend()), ans); CheckRangeEqArray(from(arr.cbegin(), arr.cend()), ans);
} }
TEST(IterRange, ArrayInt) TEST(Ctor, ArrayInt)
{ {
int arr[] = {1,2,3,4,5}; int arr[] = {1,2,3,4,5};
int * ptr = static_cast<int *>(arr); int * ptr = static_cast<int *>(arr);
...@@ -104,13 +104,13 @@ TEST(IterRange, ArrayInt) ...@@ -104,13 +104,13 @@ TEST(IterRange, ArrayInt)
int ans[] = {1,2,3,4,5}; int ans[] = {1,2,3,4,5};
CheckRangeEqArray(from(arr), ans); CheckRangeEqArray(from(arr), ans);
CheckRangeEqArray(from<int>(ptr, 5), ans); CheckRangeEqArray(from(ptr, 5), ans);
CheckRangeEqArray(from<int>(ptr, ptr+5), ans); CheckRangeEqArray(from(ptr, ptr + 5), ans);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
TEST(IterRange, OneElement) TEST(Ctor, OneElement)
{ {
int src[] = {5}; int src[] = {5};
int ans[] = {5}; int ans[] = {5};
...@@ -120,11 +120,11 @@ TEST(IterRange, OneElement) ...@@ -120,11 +120,11 @@ TEST(IterRange, OneElement)
CheckRangeEqArray(rng, ans); CheckRangeEqArray(rng, ans);
} }
TEST(IterRange, EmptyVector) TEST(Ctor, EmptyVector)
{ {
std::vector<int> src; std::vector<int> src;
auto rng = from(src); auto rng = from(src);
EXPECT_THROW(rng.nextObject(), EnumeratorEndException); EXPECT_THROW(rng.next(), LinqEndException);
} }
...@@ -10,7 +10,7 @@ using namespace boolinq; ...@@ -10,7 +10,7 @@ using namespace boolinq;
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
TEST(DistinctRange, Ints1to6) TEST(Distinct, Ints1to6)
{ {
int src[] = {4,5,3,1,4,2,1,4,6}; int src[] = {4,5,3,1,4,2,1,4,6};
int ans[] = {1,2,3,4,5,6}; int ans[] = {1,2,3,4,5,6};
...@@ -21,7 +21,7 @@ TEST(DistinctRange, Ints1to6) ...@@ -21,7 +21,7 @@ TEST(DistinctRange, Ints1to6)
CheckRangeEqSet(dst, ans); CheckRangeEqSet(dst, ans);
} }
TEST(DistinctRange, IntMirrorFront) TEST(Distinct, IntMirrorFront)
{ {
int src[] = {3,2,1,0,1,2,3}; int src[] = {3,2,1,0,1,2,3};
int ans[] = {0,1,2,3}; int ans[] = {0,1,2,3};
...@@ -32,7 +32,7 @@ TEST(DistinctRange, IntMirrorFront) ...@@ -32,7 +32,7 @@ TEST(DistinctRange, IntMirrorFront)
CheckRangeEqSet(dst, ans); CheckRangeEqSet(dst, ans);
} }
TEST(DistinctRange, ManyEqualsFront) TEST(Distinct, ManyEqualsFront)
{ {
int src[] = {1,1,1,1}; int src[] = {1,1,1,1};
int ans[] = {1}; int ans[] = {1};
...@@ -43,7 +43,7 @@ TEST(DistinctRange, ManyEqualsFront) ...@@ -43,7 +43,7 @@ TEST(DistinctRange, ManyEqualsFront)
CheckRangeEqSet(dst, ans); CheckRangeEqSet(dst, ans);
} }
TEST(DistinctRange, ManyEqualsWithOneFront) TEST(Distinct, ManyEqualsWithOneFront)
{ {
int src[] = {1,1,2,1}; int src[] = {1,1,2,1};
int ans[] = {1,2}; int ans[] = {1,2};
...@@ -54,7 +54,7 @@ TEST(DistinctRange, ManyEqualsWithOneFront) ...@@ -54,7 +54,7 @@ TEST(DistinctRange, ManyEqualsWithOneFront)
CheckRangeEqSet(dst, ans); CheckRangeEqSet(dst, ans);
} }
TEST(DistinctRange, OneFieldFront) TEST(Distinct, OneFieldFront)
{ {
struct Man struct Man
{ {
......
...@@ -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);
......
#include <list>
#include <vector>
#include <string>
#include <gtest/gtest.h>
#include "boolinq.h"
using namespace boolinq;
TEST(First, ThreeElements)
{
std::vector<int> src = {1,2,3};
EXPECT_EQ(1, from(src).first());
EXPECT_EQ(2, from(src).first([](int a){return a%2 == 0;}));
EXPECT_EQ(1, from(src).firstOrDefault());
EXPECT_EQ(2, from(src).firstOrDefault([](int a){return a%2 == 0;}));
}
TEST(First, OneElement)
{
std::vector<int> src = {1};
EXPECT_EQ(1, from(src).first());
EXPECT_THROW(from(src).first([](int a){return a%2 == 0;}), LinqEndException);
EXPECT_EQ(1, from(src).firstOrDefault());
EXPECT_EQ(0, from(src).firstOrDefault([](int a){return a%2 == 0;}));
}
TEST(First, NoneElements)
{
std::vector<int> src = {};
EXPECT_THROW(from(src).first(), LinqEndException);
EXPECT_THROW(from(src).first([](int a){return a%2 == 0;}), LinqEndException);
EXPECT_EQ(0, from(src).firstOrDefault());
EXPECT_EQ(0, from(src).firstOrDefault([](int a){return a%2 == 0;}));
}
...@@ -16,7 +16,7 @@ TEST(ForEach, ThreeCharsSum) ...@@ -16,7 +16,7 @@ TEST(ForEach, ThreeCharsSum)
src.push_back('c'); src.push_back('c');
std::string str = ""; std::string str = "";
from(src).foreach([&](char a){str += a;}); from(src).for_each([&](char a){str += a;});
EXPECT_EQ("abc", str); EXPECT_EQ("abc", str);
} }
...@@ -29,7 +29,7 @@ TEST(ForEach, ThreeCharsUpperSum) ...@@ -29,7 +29,7 @@ TEST(ForEach, ThreeCharsUpperSum)
src.push_back('c'); src.push_back('c');
std::string str = ""; std::string str = "";
from(src).foreach([&](char a){str += a + ('A' - 'a');}); from(src).for_each([&](char a){str += a + ('A' - 'a');});
EXPECT_EQ("ABC", str); EXPECT_EQ("ABC", str);
} }
...@@ -42,7 +42,7 @@ TEST(ForEach, ThreeIntsSum) ...@@ -42,7 +42,7 @@ TEST(ForEach, ThreeIntsSum)
src.push_back(30); src.push_back(30);
int sum = 0; int sum = 0;
from(src).foreach([&](int a){sum += a;}); from(src).for_each([&](int a){sum += a;});
EXPECT_EQ(60, sum); EXPECT_EQ(60, sum);
} }
#include <vector>
#include <string>
#include <gtest/gtest.h>
#include "CommonTests.h"
#include "boolinq.h"
using namespace boolinq;
//////////////////////////////////////////////////////////////////////////
/*
TEST(GroupByRange, IntsFront)
{
int arr[] = {0,1,2,3,4,5,6,7,8,9};
int ans_1[] = {1,4,7};
int ans_2[] = {2,5,8};
int ans_0[] = {0,3,6,9};
auto rng = from(arr);
auto dst = rng.groupBy([](int a){return a % 3;});
EXPECT_EQ(1, dst.front().key());
EXPECT_EQ(0, dst.back().key());
CheckRangeEqArray(dst.front(), ans_1);
CheckRangeEqArray(dst.back(), ans_0);
CheckRangeEqArray(dst.popFront(), ans_1);
EXPECT_EQ(2, dst.front().key());
EXPECT_EQ(0, dst.back().key());
CheckRangeEqArray(dst.front(), ans_2);
CheckRangeEqArray(dst.back(), ans_0);
CheckRangeEqArray(dst.popFront(), ans_2);
EXPECT_EQ(0, dst.front().key());
EXPECT_EQ(0, dst.back().key());
CheckRangeEqArray(dst.front(), ans_0);
CheckRangeEqArray(dst.back(), ans_0);
CheckRangeEqArray(dst.popFront(), ans_0);
EXPECT_THROW(dst.nextObject(), EnumeratorEndException);
}
TEST(GroupByRange, IntsBack)
{
int arr[] = {0,1,2,3,4,5,6,7,8,9};
int ans_1[] = {1,4,7};
int ans_2[] = {2,5,8};
int ans_0[] = {0,3,6,9};
auto rng = from(arr);
auto dst = groupBy(rng, [](int a){return a % 3;});
EXPECT_EQ(1, dst.front().key());
EXPECT_EQ(0, dst.back().key());
CheckRangeEqArray(dst.front(), ans_1);
CheckRangeEqArray(dst.back(), ans_0);
CheckRangeEqArray(dst.popBack(), ans_0);
EXPECT_EQ(1, dst.front().key());
EXPECT_EQ(2, dst.back().key());
CheckRangeEqArray(dst.front(), ans_1);
CheckRangeEqArray(dst.back(), ans_2);
CheckRangeEqArray(dst.popBack(), ans_2);
EXPECT_EQ(1, dst.front().key());
EXPECT_EQ(1, dst.back().key());
CheckRangeEqArray(dst.front(), ans_1);
CheckRangeEqArray(dst.back(), ans_1);
CheckRangeEqArray(dst.popBack(), ans_1);
EXPECT_THROW(dst.nextObject(), EnumeratorEndException);
}
//////////////////////////////////////////////////////////////////////////
TEST(GroupByRange, CountChildrenByAge)
{
struct Child
{
std::string name;
int age;
bool operator == (const Child & rhs) const
{
return (name == rhs.name) && (age == rhs.age);
}
};
Child children[] =
{
{"Piter", 12},
{"Bella", 14},
{"Torry", 15},
{"Holly", 12},
{"Zamza", 13},
};
Child ans_false[] =
{
{"Bella", 14},
{"Torry", 15},
};
Child ans_true[] =
{
{"Piter", 12},
{"Holly", 12},
{"Zamza", 13},
};
auto rng = from(children);
auto dst = groupBy(rng, [](const Child & a){return a.age < 14;});
EXPECT_EQ(false, dst.front().key());
CheckRangeEqArray(dst.front(), ans_false);
CheckRangeEqArray(dst.back(), ans_true);
CheckRangeEqArray(dst.popFront(), ans_false);
EXPECT_EQ(true, dst.front().key());
CheckRangeEqArray(dst.front(), ans_true);
CheckRangeEqArray(dst.back(), ans_true);
CheckRangeEqArray(dst.popFront(), ans_true);
EXPECT_THROW(dst.nextObject(), EnumeratorEndException);
}
*/
#include <vector>
#include <string>
#include <gtest/gtest.h>
#include "CommonTests.h"
#include "boolinq.h"
using namespace boolinq;
//////////////////////////////////////////////////////////////////////////
TEST(GroupBy, Ints)
{
int arr[] = {0,1,2,3,4,5,6,7,8,9};
int ans_0[] = {0,3,6,9};
int ans_1[] = {1,4,7};
int ans_2[] = {2,5,8};
auto dst = from(arr).groupBy([](int a){return a % 3;});
EXPECT_EQ(0, dst.elementAt(0).first);
EXPECT_EQ(1, dst.elementAt(1).first);
EXPECT_EQ(2, dst.elementAt(2).first);
CheckRangeEqArray(dst.elementAt(0).second, ans_0);
CheckRangeEqArray(dst.elementAt(1).second, ans_1);
CheckRangeEqArray(dst.elementAt(2).second, ans_2);
EXPECT_THROW(dst.elementAt(3), LinqEndException);
}
//////////////////////////////////////////////////////////////////////////
TEST(GroupBy, CountChildrenByAge)
{
struct Child
{
std::string name;
int age;
bool operator == (const Child & rhs) const
{
return (name == rhs.name) && (age == rhs.age);
}
};
Child children[] = {
{"Piter", 12},
{"Bella", 14},
{"Torry", 15},
{"Holly", 12},
{"Zamza", 13},
};
Child ans_false[] = {
{"Bella", 14},
{"Torry", 15},
};
Child ans_true[] = {
{"Piter", 12},
{"Holly", 12},
{"Zamza", 13},
};
auto dst = from(children).groupBy([](const Child & a){return a.age < 14;});
EXPECT_EQ(true, dst.elementAt(0).first);
EXPECT_EQ(false, dst.elementAt(1).first);
CheckRangeEqArray(dst.elementAt(0).second, ans_true);
CheckRangeEqArray(dst.elementAt(1).second, ans_false);
EXPECT_THROW(dst.elementAt(2), LinqEndException);
}
#include <list>
#include <vector>
#include <string>
#include <gtest/gtest.h>
#include "boolinq.h"
using namespace boolinq;
TEST(Last, ThreeElements)
{
std::vector<int> src = {1,2,3};
EXPECT_EQ(3, from(src).last());
EXPECT_EQ(2, from(src).last([](int a){return a%2 == 0;}));
EXPECT_EQ(3, from(src).lastOrDefault());
EXPECT_EQ(2, from(src).lastOrDefault([](int a){return a%2 == 0;}));
}
TEST(Last, OneElement)
{
std::vector<int> src = {1};
EXPECT_EQ(1, from(src).last());
EXPECT_THROW(from(src).last([](int a){return a%2 == 0;}), LinqEndException);
EXPECT_EQ(1, from(src).lastOrDefault());
EXPECT_EQ(0, from(src).lastOrDefault([](int a){return a%2 == 0;}));
}
TEST(Last, NoneElements)
{
std::vector<int> src = {};
EXPECT_THROW(from(src).last(), LinqEndException);
EXPECT_THROW(from(src).last([](int a){return a%2 == 0;}), LinqEndException);
EXPECT_EQ(0, from(src).lastOrDefault());
EXPECT_EQ(0, from(src).lastOrDefault([](int a){return a%2 == 0;}));
}
...@@ -25,10 +25,10 @@ TEST(Linq, WhereOdd) ...@@ -25,10 +25,10 @@ TEST(Linq, WhereOdd)
for (int i = 1; i <= 5; i+=2) for (int i = 1; i <= 5; i+=2)
{ {
EXPECT_EQ(i, rng.nextObject()); EXPECT_EQ(i, rng.next());
} }
EXPECT_THROW(rng.nextObject(), EnumeratorEndException); EXPECT_THROW(rng.next(), LinqEndException);
} }
TEST(Linq, WhereOdd_WhereLess) TEST(Linq, WhereOdd_WhereLess)
...@@ -48,10 +48,10 @@ TEST(Linq, WhereOdd_WhereLess) ...@@ -48,10 +48,10 @@ TEST(Linq, WhereOdd_WhereLess)
for (int i = 1; i <= 3; i+=2) for (int i = 1; i <= 3; i+=2)
{ {
EXPECT_EQ(i, rng.nextObject()); EXPECT_EQ(i, rng.next());
} }
EXPECT_THROW(rng.nextObject(), EnumeratorEndException); EXPECT_THROW(rng.next(), LinqEndException);
} }
TEST(Linq, WhereLess_WhereOdd) TEST(Linq, WhereLess_WhereOdd)
...@@ -68,7 +68,7 @@ TEST(Linq, WhereLess_WhereOdd) ...@@ -68,7 +68,7 @@ TEST(Linq, WhereLess_WhereOdd)
auto rng = from(src).where([](int a){return a < 4;}) auto rng = from(src).where([](int a){return a < 4;})
.where([](int a){return a%2 == 1;}) .where([](int a){return a%2 == 1;})
.toVector(); .toStdVector();
std::vector<int> ans; std::vector<int> ans;
ans.push_back(1); ans.push_back(1);
...@@ -92,7 +92,7 @@ TEST(Linq, WhereLess_WhereOdd_OrderByDesc) ...@@ -92,7 +92,7 @@ TEST(Linq, WhereLess_WhereOdd_OrderByDesc)
auto rng = from(src).where([](int a){return a < 6;}) auto rng = from(src).where([](int a){return a < 6;})
.where([](int a){return a%2 == 1;}) .where([](int a){return a%2 == 1;})
.orderBy([](int a){return -a;}) .orderBy([](int a){return -a;})
.toVector(); .toStdVector();
std::vector<int> ans; std::vector<int> ans;
ans.push_back(5); ans.push_back(5);
...@@ -115,7 +115,7 @@ TEST(Linq, WhereOdd_ToVector) ...@@ -115,7 +115,7 @@ TEST(Linq, WhereOdd_ToVector)
src.push_back(8); src.push_back(8);
auto dst = from(src).where([](int a){return a%2 == 1;}) auto dst = from(src).where([](int a){return a%2 == 1;})
.toVector(); .toStdVector();
std::vector<int> ans; std::vector<int> ans;
ans.push_back(1); ans.push_back(1);
...@@ -141,7 +141,7 @@ TEST(Linq, WhereOdd_WhereLess_SelectMul2_ToVector) ...@@ -141,7 +141,7 @@ TEST(Linq, WhereOdd_WhereLess_SelectMul2_ToVector)
auto dst = from(src).where([](int a){return a%2 == 1;}) auto dst = from(src).where([](int a){return a%2 == 1;})
.where([](int a){return a < 6;}) .where([](int a){return a < 6;})
.select([](int a){return a*2;}) .select([](int a){return a*2;})
.toVector(); .toStdVector();
std::vector<int> ans; std::vector<int> ans;
ans.push_back(2); ans.push_back(2);
...@@ -167,7 +167,7 @@ TEST(Linq, WhereOdd_WhereLess_SelectMul2_Reverse_ToVector) ...@@ -167,7 +167,7 @@ TEST(Linq, WhereOdd_WhereLess_SelectMul2_Reverse_ToVector)
.where([](int a){return a < 6;}) .where([](int a){return a < 6;})
.select([](int a){return a*2;}) .select([](int a){return a*2;})
.reverse() .reverse()
.toVector(); .toStdVector();
std::vector<int> ans; std::vector<int> ans;
ans.push_back(10); ans.push_back(10);
...@@ -193,7 +193,7 @@ TEST(Linq, WhereOdd_Reverse_Reverse) ...@@ -193,7 +193,7 @@ TEST(Linq, WhereOdd_Reverse_Reverse)
.reverse() .reverse()
.where([](int a){return a < 4;}) .where([](int a){return a < 4;})
.reverse() .reverse()
.toVector(); .toStdVector();
std::vector<int> ans; std::vector<int> ans;
ans.push_back(1); ans.push_back(1);
...@@ -208,14 +208,14 @@ TEST(Linq, Pointer_Front) ...@@ -208,14 +208,14 @@ TEST(Linq, Pointer_Front)
{ {
int src[] = {1,2,3,4,5}; int src[] = {1,2,3,4,5};
auto dst = from<int>(static_cast<int *>(src), static_cast<int *>(src) + 5); auto dst = from(static_cast<int *>(src), static_cast<int *>(src) + 5);
for(int i = 1; i <= 5; i++) for(int i = 1; i <= 5; i++)
{ {
EXPECT_EQ(i, dst.nextObject()); EXPECT_EQ(i, dst.next());
} }
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.next(), LinqEndException);
} }
...@@ -229,10 +229,10 @@ TEST(Linq, Array_Front) ...@@ -229,10 +229,10 @@ TEST(Linq, Array_Front)
for(int i = 1; i <= 5; i++) for(int i = 1; i <= 5; i++)
{ {
EXPECT_EQ(i, dst.nextObject()); EXPECT_EQ(i, dst.next());
} }
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.next(), LinqEndException);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
...@@ -253,12 +253,12 @@ TEST(Linq, Creations) ...@@ -253,12 +253,12 @@ TEST(Linq, Creations)
auto dst_vec = from(vec); auto dst_vec = from(vec);
auto dst_arr = from(arr); auto dst_arr = from(arr);
//auto dst_carr = from(carr); //auto dst_carr = from(carr);
auto dst_ptr = from<int>(ptr, ptr+5); auto dst_ptr = from(ptr, ptr+5);
//auto dst_cptr = from<const int>(cptr, cptr+5); //auto dst_cptr = from(cptr, cptr+5);
auto dst_ptr_length = from<int>(ptr, 5); auto dst_ptr_length = from(ptr, 5);
//auto dst_cptr_length = from<const int>(cptr, 5); //auto dst_cptr_length = from(cptr, 5);
auto dst_vec_iter = from<int>(vec.begin(), vec.end()); auto dst_vec_iter = from(vec.begin(), vec.end());
//auto dst_vec_citer = from<const int>(vec.cbegin(), vec.cend()); //auto dst_vec_citer = from(vec.cbegin(), vec.cend());
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
...@@ -301,8 +301,8 @@ TEST(Linq, MessagesCountUniqueContacts) ...@@ -301,8 +301,8 @@ TEST(Linq, MessagesCountUniqueContacts)
TEST(Linq, ForwardIterating) TEST(Linq, ForwardIterating)
{ {
std::stringstream stream("0123456789"); std::stringstream stream("0123456789");
auto dst = from<char>(std::istream_iterator<char>(stream), auto dst = from(std::istream_iterator<char>(stream),
std::istream_iterator<char>()) std::istream_iterator<char>())
.where( [](char a){return a % 2 == 0;}) .where( [](char a){return a % 2 == 0;})
.select([](char a){return std::string(1,a);}) .select([](char a){return std::string(1,a);})
.sum(); .sum();
......
...@@ -10,7 +10,7 @@ using namespace boolinq; ...@@ -10,7 +10,7 @@ using namespace boolinq;
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
TEST(OrderByRange, RandomIntsWithDuplicates) TEST(OrderBy, RandomIntsWithDuplicates)
{ {
int src[] = {4,5,3,1,4,2,1,4,6}; int src[] = {4,5,3,1,4,2,1,4,6};
int ans[] = {1,1,2,3,4,4,4,5,6}; int ans[] = {1,1,2,3,4,4,4,5,6};
...@@ -21,7 +21,7 @@ TEST(OrderByRange, RandomIntsWithDuplicates) ...@@ -21,7 +21,7 @@ TEST(OrderByRange, RandomIntsWithDuplicates)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(OrderByRange, ReverseInts) TEST(OrderBy, ReverseInts)
{ {
int src[] = {4,3,2,1}; int src[] = {4,3,2,1};
int ans[] = {1,2,3,4}; int ans[] = {1,2,3,4};
...@@ -32,7 +32,7 @@ TEST(OrderByRange, ReverseInts) ...@@ -32,7 +32,7 @@ TEST(OrderByRange, ReverseInts)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(OrderByRange, ThreeElements) TEST(OrderBy, ThreeElements)
{ {
int src[] = {1,3,2}; int src[] = {1,3,2};
int ans[] = {1,2,3}; int ans[] = {1,2,3};
...@@ -45,7 +45,7 @@ TEST(OrderByRange, ThreeElements) ...@@ -45,7 +45,7 @@ TEST(OrderByRange, ThreeElements)
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
TEST(OrderByRange, OneElement) TEST(OrderBy, OneElement)
{ {
int src[] = {5}; int src[] = {5};
int ans[] = {5}; int ans[] = {5};
...@@ -56,19 +56,19 @@ TEST(OrderByRange, OneElement) ...@@ -56,19 +56,19 @@ TEST(OrderByRange, OneElement)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(OrderByRange, NoElements) TEST(OrderBy, NoElements)
{ {
std::vector<int> src; std::vector<int> src;
auto rng = from(src); auto rng = from(src);
auto dst = rng.orderBy(); auto dst = rng.orderBy();
EXPECT_THROW(dst.nextObject(), EnumeratorEndException); EXPECT_THROW(dst.next(), LinqEndException);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
TEST(OrderByRange, RandomStringByContent) TEST(OrderBy, RandomStringByContent)
{ {
std::string src[] = std::string src[] =
{ {
...@@ -96,7 +96,7 @@ TEST(OrderByRange, RandomStringByContent) ...@@ -96,7 +96,7 @@ TEST(OrderByRange, RandomStringByContent)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(OrderByRange, RandomStringByLength) TEST(OrderBy, RandomStringByLength)
{ {
std::string src[] = std::string src[] =
{ {
......
#include <vector>
#include <string>
#include <gtest/gtest.h>
#include "CommonTests.h"
#include "boolinq.h"
using namespace boolinq;
TEST(Prepend, ThreePlusOne)
{
std::vector<int> src = {1,2,3};
auto rng = from(src).prepend(4);
int ans[] = {4,1,2,3};
CheckRangeEqArray(rng, ans);
}
TEST(Prepend, ThreePlusTwo)
{
std::vector<int> src = {1,2,3};
auto rng = from(src).prepend(4, 5);
int ans[] = {4,5,1,2,3};
CheckRangeEqArray(rng, ans);
}
TEST(Prepend, ZeroPlusTwo)
{
std::vector<int> src;
auto rng = from(src).prepend(7,8);
int ans[] = {7,8};
CheckRangeEqArray(rng, ans);
}
\ No newline at end of file
#include <vector>
#include <string>
#include <gtest/gtest.h>
#include "CommonTests.h"
#include "boolinq.h"
using namespace boolinq;
TEST(Range, OneToFive)
{
int ans[] = {1,2,3,4};
CheckRangeEqArray(range(1,5,1), ans);
}
TEST(Range, OneToFiveStep2)
{
int ans[] = {1,3};
CheckRangeEqArray(range(1,5,2), ans);
}
\ No newline at end of file
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
using namespace boolinq; using namespace boolinq;
TEST(ReverseRange, IntVector) TEST(Reverse, IntVector)
{ {
int src[] = {1,2,3,4}; int src[] = {1,2,3,4};
int ans[] = {4,3,2,1}; int ans[] = {4,3,2,1};
...@@ -21,7 +21,7 @@ TEST(ReverseRange, IntVector) ...@@ -21,7 +21,7 @@ TEST(ReverseRange, IntVector)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(ReverseRange, DoubleReverse) TEST(Reverse, DoubleReverse)
{ {
int src[] = {1,2,3,4}; int src[] = {1,2,3,4};
int ans[] = {1,2,3,4}; int ans[] = {1,2,3,4};
......
#include <vector>
#include <string>
#include <gtest/gtest.h>
#include "CommonTests.h"
#include "boolinq.h"
using namespace boolinq;
TEST(SelectMany, AxA)
{
int src[] = {1,2,3};
int ans[] = {1,2,2,3,3,3};
auto rng = from(src);
auto dst = rng.selectMany([](int a){return repeat(a, a);});
CheckRangeEqArray(dst, ans);
}
TEST(SelectMany, OneTwoThree)
{
int src[] = {1,2,3};
int ans[] = {1,2,3,2,4,6,3,6,9};
auto rng = from(src);
auto dst = rng.selectMany([&src](int a){
return from(src).select([a](int v){return a*v;});
});
CheckRangeEqArray(dst, ans);
}
\ No newline at end of file
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
using namespace boolinq; using namespace boolinq;
TEST(SelectRange, Mul2) TEST(Select, Mul2)
{ {
int src[] = {1,2,3,4}; int src[] = {1,2,3,4};
int ans[] = {2,4,6,8}; int ans[] = {2,4,6,8};
...@@ -19,7 +19,7 @@ TEST(SelectRange, Mul2) ...@@ -19,7 +19,7 @@ TEST(SelectRange, Mul2)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(SelectRange, MakeChar) TEST(Select, MakeChar)
{ {
int src[] = {1,2,3,4}; int src[] = {1,2,3,4};
char ans[] = {'1','2','3','4'}; char ans[] = {'1','2','3','4'};
...@@ -30,7 +30,7 @@ TEST(SelectRange, MakeChar) ...@@ -30,7 +30,7 @@ TEST(SelectRange, MakeChar)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(SelectRange, MakeString) TEST(Select, MakeString)
{ {
int src[] = {1,2,3,4}; int src[] = {1,2,3,4};
......
...@@ -10,7 +10,7 @@ using namespace boolinq; ...@@ -10,7 +10,7 @@ using namespace boolinq;
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
TEST(SkipRange, ManyToMany) TEST(Skip, ManyToMany)
{ {
int src[] = {1,2,3,4,5,6}; int src[] = {1,2,3,4,5,6};
int ans[] = {1,2,3,4,5,6}; int ans[] = {1,2,3,4,5,6};
...@@ -21,7 +21,7 @@ TEST(SkipRange, ManyToMany) ...@@ -21,7 +21,7 @@ TEST(SkipRange, ManyToMany)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(SkipRange, ManyToLess) TEST(Skip, ManyToLess)
{ {
int src[] = {1,2,3,4,5,6}; int src[] = {1,2,3,4,5,6};
int ans[] = {4,5,6}; int ans[] = {4,5,6};
...@@ -32,7 +32,7 @@ TEST(SkipRange, ManyToLess) ...@@ -32,7 +32,7 @@ TEST(SkipRange, ManyToLess)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(SkipRange, ManyToOne) TEST(Skip, ManyToOne)
{ {
int src[] = {1,2,3,4,5,6}; int src[] = {1,2,3,4,5,6};
int ans[] = {6}; int ans[] = {6};
...@@ -43,29 +43,29 @@ TEST(SkipRange, ManyToOne) ...@@ -43,29 +43,29 @@ TEST(SkipRange, ManyToOne)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(SkipRange, ManyToZero) TEST(Skip, ManyToZero)
{ {
int src[] = {1,2,3,4,5,6}; int src[] = {1,2,3,4,5,6};
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.next(), LinqEndException);
} }
TEST(SkipRange, ManyToZeroLess) TEST(Skip, ManyToZeroLess)
{ {
int src[] = {1,2,3,4,5,6}; int src[] = {1,2,3,4,5,6};
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.next(), LinqEndException);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
TEST(SkipRange, OneToOne) TEST(Skip, OneToOne)
{ {
int src[] = {5}; int src[] = {5};
int ans[] = {5}; int ans[] = {5};
...@@ -76,44 +76,44 @@ TEST(SkipRange, OneToOne) ...@@ -76,44 +76,44 @@ TEST(SkipRange, OneToOne)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(SkipRange, OneToZero) TEST(Skip, OneToZero)
{ {
int src[] = {5}; int src[] = {5};
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.next(), LinqEndException);
} }
TEST(SkipRange, OneToZeroLess) TEST(Skip, OneToZeroLess)
{ {
int src[] = {5}; int src[] = {5};
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.next(), LinqEndException);
} }
TEST(SkipRange, ZeroToZero) TEST(Skip, ZeroToZero)
{ {
std::vector<int> src; std::vector<int> src;
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.next(), LinqEndException);
} }
TEST(SkipRange, ZeroToZeroLess) TEST(Skip, ZeroToZeroLess)
{ {
std::vector<int> src; std::vector<int> src;
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.next(), LinqEndException);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
...@@ -10,7 +10,7 @@ using namespace boolinq; ...@@ -10,7 +10,7 @@ using namespace boolinq;
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
TEST(SkipWhileRange, ManyToMore) TEST(SkipWhile, ManyToMore)
{ {
int src[] = {1,2,3,4,5,6}; int src[] = {1,2,3,4,5,6};
int ans[] = {1,2,3,4,5,6}; int ans[] = {1,2,3,4,5,6};
...@@ -54,7 +54,7 @@ TEST(SkipWhileRange_i, ManyToMoreByIndexAndItemValue) ...@@ -54,7 +54,7 @@ TEST(SkipWhileRange_i, ManyToMoreByIndexAndItemValue)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(SkipWhileRange, ManyToMany) TEST(SkipWhile, ManyToMany)
{ {
int src[] = {1,2,3,4,5,6}; int src[] = {1,2,3,4,5,6};
int ans[] = {1,2,3,4,5,6}; int ans[] = {1,2,3,4,5,6};
...@@ -99,7 +99,7 @@ TEST(SkipWhileRange_i, ManyToManyByIndexAndItemValue) ...@@ -99,7 +99,7 @@ TEST(SkipWhileRange_i, ManyToManyByIndexAndItemValue)
} }
TEST(SkipWhileRange, ManyToLess) TEST(SkipWhile, ManyToLess)
{ {
int src[] = {1,2,3,4,5,6}; int src[] = {1,2,3,4,5,6};
int ans[] = {3,4,5,6}; int ans[] = {3,4,5,6};
...@@ -143,7 +143,7 @@ TEST(SkipWhileRange_i, ManyToLessByIndexAndItemValue) ...@@ -143,7 +143,7 @@ TEST(SkipWhileRange_i, ManyToLessByIndexAndItemValue)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(SkipWhileRange, ManyToOne) TEST(SkipWhile, ManyToOne)
{ {
int src[] = {1,2,3,4,5,6}; int src[] = {1,2,3,4,5,6};
int ans[] = {6}; int ans[] = {6};
...@@ -187,14 +187,14 @@ TEST(SkipWhileRange_i, ManyToOneByIndexAndItemValue) ...@@ -187,14 +187,14 @@ TEST(SkipWhileRange_i, ManyToOneByIndexAndItemValue)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(SkipWhileRange, ManyToZero) TEST(SkipWhile, ManyToZero)
{ {
int src[] = {1,2,3,4,5,6}; int src[] = {1,2,3,4,5,6};
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.next(), 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.next(), 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.next(), LinqEndException);
} }
TEST(SkipWhileRange_i, ManyToZeroIndexAndItemValue) TEST(SkipWhileRange_i, ManyToZeroIndexAndItemValue)
...@@ -224,12 +224,12 @@ TEST(SkipWhileRange_i, ManyToZeroIndexAndItemValue) ...@@ -224,12 +224,12 @@ 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.next(), LinqEndException);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
TEST(SkipWhileRange, OneToOne) TEST(SkipWhile, OneToOne)
{ {
int src[] = {5}; int src[] = {5};
int ans[] = {5}; int ans[] = {5};
...@@ -273,14 +273,14 @@ TEST(SkipWhileRange_i, OneToOneByIndexAndItemValue) ...@@ -273,14 +273,14 @@ TEST(SkipWhileRange_i, OneToOneByIndexAndItemValue)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(SkipWhileRange, OneToZero) TEST(SkipWhile, OneToZero)
{ {
int src[] = {5}; int src[] = {5};
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.next(), 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.next(), 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.next(), LinqEndException);
} }
TEST(SkipWhileRange_i, OneToZeroIndexAndItemValue) TEST(SkipWhileRange_i, OneToZeroIndexAndItemValue)
...@@ -310,17 +310,17 @@ TEST(SkipWhileRange_i, OneToZeroIndexAndItemValue) ...@@ -310,17 +310,17 @@ 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.next(), LinqEndException);
} }
TEST(SkipWhileRange, ZeroToZero) TEST(SkipWhile, ZeroToZero)
{ {
std::vector<int> src; std::vector<int> src;
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.next(), 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.next(), LinqEndException);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
...@@ -36,7 +36,7 @@ TEST(Sum, FiveInts) ...@@ -36,7 +36,7 @@ TEST(Sum, FiveInts)
EXPECT_EQ(9, dst1); EXPECT_EQ(9, dst1);
} }
TEST(Sum, BoolSum) TEST(Sum, TransformSum)
{ {
std::vector<int> src; std::vector<int> src;
src.push_back(1); src.push_back(1);
...@@ -45,10 +45,10 @@ TEST(Sum, BoolSum) ...@@ -45,10 +45,10 @@ TEST(Sum, BoolSum)
src.push_back(4); src.push_back(4);
src.push_back(5); src.push_back(5);
auto rng1 = from(src).sum<int>([](int a){return a%2 == 0;}); auto rng1 = from(src).sum([](int a){return a/2;});
auto rng2 = from(src).sum<int>([](int a){return a%2 == 1;}); auto rng2 = from(src).sum([](int a){return a%2;});
EXPECT_EQ(2, rng1); EXPECT_EQ(6, rng1);
EXPECT_EQ(3, rng2); EXPECT_EQ(3, rng2);
} }
...@@ -81,3 +81,17 @@ TEST(Sum, FiveStringsData) ...@@ -81,3 +81,17 @@ TEST(Sum, FiveStringsData)
EXPECT_EQ(ans, rng); EXPECT_EQ(ans, rng);
} }
TEST(Sum, TransfromStringSum)
{
std::vector<std::string> src;
src.push_back("hello");
src.push_back("apple");
src.push_back("nokia");
src.push_back("oracle");
src.push_back("ponny");
auto sum = from(src).sum([](std::string s) { return s.size(); });
EXPECT_EQ(26, sum);
}
...@@ -10,7 +10,7 @@ using namespace boolinq; ...@@ -10,7 +10,7 @@ using namespace boolinq;
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
TEST(TakeRange, ManyToMore) TEST(Take, ManyToMore)
{ {
int src[] = {1,2,3,4,5,6}; int src[] = {1,2,3,4,5,6};
int ans[] = {1,2,3,4,5,6}; int ans[] = {1,2,3,4,5,6};
...@@ -21,7 +21,7 @@ TEST(TakeRange, ManyToMore) ...@@ -21,7 +21,7 @@ TEST(TakeRange, ManyToMore)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(TakeRange, ManyToMany) TEST(Take, ManyToMany)
{ {
int src[] = {1,2,3,4,5,6}; int src[] = {1,2,3,4,5,6};
int ans[] = {1,2,3,4,5,6}; int ans[] = {1,2,3,4,5,6};
...@@ -32,7 +32,7 @@ TEST(TakeRange, ManyToMany) ...@@ -32,7 +32,7 @@ TEST(TakeRange, ManyToMany)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(TakeRange, ManyToLess) TEST(Take, ManyToLess)
{ {
int src[] = {1,2,3,4,5,6}; int src[] = {1,2,3,4,5,6};
int ans[] = {1,2,3}; int ans[] = {1,2,3};
...@@ -43,7 +43,7 @@ TEST(TakeRange, ManyToLess) ...@@ -43,7 +43,7 @@ TEST(TakeRange, ManyToLess)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(TakeRange, ManyToOne) TEST(Take, ManyToOne)
{ {
int src[] = {1,2,3,4,5,6}; int src[] = {1,2,3,4,5,6};
int ans[] = {1}; int ans[] = {1};
...@@ -54,19 +54,19 @@ TEST(TakeRange, ManyToOne) ...@@ -54,19 +54,19 @@ TEST(TakeRange, ManyToOne)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(TakeRange, ManyToZero) TEST(Take, ManyToZero)
{ {
int src[] = {1,2,3,4,5,6}; int src[] = {1,2,3,4,5,6};
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.next(), LinqEndException);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
TEST(TakeRange, OneToMore) TEST(Take, OneToMore)
{ {
int src[] = {5}; int src[] = {5};
int ans[] = {5}; int ans[] = {5};
...@@ -77,7 +77,7 @@ TEST(TakeRange, OneToMore) ...@@ -77,7 +77,7 @@ TEST(TakeRange, OneToMore)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(TakeRange, OneToOne) TEST(Take, OneToOne)
{ {
int src[] = {5}; int src[] = {5};
int ans[] = {5}; int ans[] = {5};
...@@ -88,24 +88,24 @@ TEST(TakeRange, OneToOne) ...@@ -88,24 +88,24 @@ TEST(TakeRange, OneToOne)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(TakeRange, OneToZero) TEST(Take, OneToZero)
{ {
int src[] = {5}; int src[] = {5};
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.next(), LinqEndException);
} }
TEST(TakeRange, ZeroToZero) TEST(Take, ZeroToZero)
{ {
std::vector<int> src; std::vector<int> src;
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.next(), LinqEndException);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
...@@ -10,7 +10,7 @@ using namespace boolinq; ...@@ -10,7 +10,7 @@ using namespace boolinq;
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
TEST(TakeWhileRange, ManyToMore) TEST(TakeWhile, ManyToMore)
{ {
int src[] = {1,2,3,4,5,6}; int src[] = {1,2,3,4,5,6};
int ans[] = {1,2,3,4,5,6}; int ans[] = {1,2,3,4,5,6};
...@@ -54,7 +54,7 @@ TEST(TakeWhileRange_i, ManyToMoreByIndexAndItemValue) ...@@ -54,7 +54,7 @@ TEST(TakeWhileRange_i, ManyToMoreByIndexAndItemValue)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(TakeWhileRange, ManyToMany) TEST(TakeWhile, ManyToMany)
{ {
int src[] = {1,2,3,4,5,6}; int src[] = {1,2,3,4,5,6};
int ans[] = {1,2,3,4,5,6}; int ans[] = {1,2,3,4,5,6};
...@@ -98,7 +98,7 @@ TEST(TakeWhileRange_i, ManyToManyByIndexAndItemValue) ...@@ -98,7 +98,7 @@ TEST(TakeWhileRange_i, ManyToManyByIndexAndItemValue)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(TakeWhileRange, ManyToLess) TEST(TakeWhile, ManyToLess)
{ {
int src[] = {1,2,3,4,5,6}; int src[] = {1,2,3,4,5,6};
int ans[] = {1,2,3}; int ans[] = {1,2,3};
...@@ -142,7 +142,7 @@ TEST(TakeWhileRange_i, ManyToLessByIndexAndItemValue) ...@@ -142,7 +142,7 @@ TEST(TakeWhileRange_i, ManyToLessByIndexAndItemValue)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(TakeWhileRange, ManyToOne) TEST(TakeWhile, ManyToOne)
{ {
int src[] = {1,2,3,4,5,6}; int src[] = {1,2,3,4,5,6};
int ans[] = {1}; int ans[] = {1};
...@@ -186,14 +186,14 @@ TEST(TakeWhileRange_i, ManyToOneByIndexAndItemValue) ...@@ -186,14 +186,14 @@ TEST(TakeWhileRange_i, ManyToOneByIndexAndItemValue)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(TakeWhileRange, ManyToZero) TEST(TakeWhile, ManyToZero)
{ {
int src[] = {1,2,3,4,5,6}; int src[] = {1,2,3,4,5,6};
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.next(), 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.next(), 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.next(), LinqEndException);
} }
TEST(TakeWhileRange_i, ManyToZeroByIdexAndItemValue) TEST(TakeWhileRange_i, ManyToZeroByIdexAndItemValue)
...@@ -223,12 +223,12 @@ TEST(TakeWhileRange_i, ManyToZeroByIdexAndItemValue) ...@@ -223,12 +223,12 @@ 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.next(), LinqEndException);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
TEST(TakeWhileRange, OneToOne) TEST(TakeWhile, OneToOne)
{ {
int src[] = {5}; int src[] = {5};
int ans[] = {5}; int ans[] = {5};
...@@ -272,14 +272,14 @@ TEST(TakeWhileRange_i, OneToOneByIndexAndItemValue) ...@@ -272,14 +272,14 @@ TEST(TakeWhileRange_i, OneToOneByIndexAndItemValue)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(TakeWhileRange, OneToZero) TEST(TakeWhile, OneToZero)
{ {
int src[] = {5}; int src[] = {5};
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.next(), 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.next(), 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.next(), LinqEndException);
} }
TEST(TakeWhileRange_i, OneToZeroByIndexAndItemValue) TEST(TakeWhileRange_i, OneToZeroByIndexAndItemValue)
...@@ -309,17 +309,17 @@ TEST(TakeWhileRange_i, OneToZeroByIndexAndItemValue) ...@@ -309,17 +309,17 @@ 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.next(), LinqEndException);
} }
TEST(TakeWhileRange, ZeroToZero) TEST(TakeWhile, ZeroToZero)
{ {
std::vector<int> src; std::vector<int> src;
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.next(), 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.next(), LinqEndException);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
#include <list>
#include <deque>
#include <vector>
#include <gtest/gtest.h>
#include "CommonTests.h"
#include "IterRange.h"
#include "ToContainer.h"
using namespace boolinq;
//////////////////////////////////////////////////////////////////////////
TEST(ToContainer, Array2List)
{
int src[] = {100,200,300};
auto rng = range(src);
auto dst = toContainer<std::list>(rng);
EXPECT_EQ(3, dst.size());
EXPECT_EQ(100, dst.front()); dst.pop_front();
EXPECT_EQ(200, dst.front()); dst.pop_front();
EXPECT_EQ(300, dst.front()); dst.pop_front();
}
TEST(ToContainer, Array2Deque)
{
int src[] = {100,200,300};
auto rng = range(src);
auto dst = toContainer<std::deque>(rng);
EXPECT_EQ(3, dst.size());
EXPECT_EQ(100, dst.front()); dst.pop_front();
EXPECT_EQ(200, dst.front()); dst.pop_front();
EXPECT_EQ(300, dst.front()); dst.pop_front();
}
TEST(ToContainer, Array2Vector)
{
int src[] = {100,200,300};
auto rng = range(src);
auto dst = toContainer<std::vector>(rng);
EXPECT_EQ(3, dst.size());
EXPECT_EQ(100, dst[0]);
EXPECT_EQ(200, dst[1]);
EXPECT_EQ(300, dst[2]);
}
//////////////////////////////////////////////////////////////////////////
TEST(ToContainer, List2List)
{
std::list<int> src;
src.push_back(100);
src.push_back(200);
src.push_back(300);
auto rng = range(src);
auto dst = toContainer<std::list>(rng);
EXPECT_EQ(dst,src);
}
TEST(ToContainer, Deque2Deque)
{
std::deque<int> src;
src.push_back(100);
src.push_back(200);
src.push_back(300);
auto rng = range(src);
auto dst = toContainer<std::deque>(rng);
EXPECT_EQ(dst,src);
}
TEST(ToContainer, Vector2Vector)
{
std::vector<int> src;
src.push_back(100);
src.push_back(200);
src.push_back(300);
auto rng = range(src);
auto dst = toContainer<std::vector>(rng);
EXPECT_EQ(dst,src);
}
//////////////////////////////////////////////////////////////////////////
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
using namespace boolinq; using namespace boolinq;
TEST(ToDeque, Deque2Deque) TEST(ToStdDeque, Deque2Deque)
{ {
std::deque<int> src; std::deque<int> src;
src.push_back(100); src.push_back(100);
...@@ -14,7 +14,7 @@ TEST(ToDeque, Deque2Deque) ...@@ -14,7 +14,7 @@ TEST(ToDeque, Deque2Deque)
src.push_back(300); src.push_back(300);
auto rng = from(src); auto rng = from(src);
auto dst = rng.toDeque(); auto dst = rng.toStdDeque();
EXPECT_EQ(dst,src); EXPECT_EQ(dst,src);
} }
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
using namespace boolinq; using namespace boolinq;
TEST(ToList, List2List) TEST(ToStdList, List2List)
{ {
std::list<int> src; std::list<int> src;
src.push_back(100); src.push_back(100);
...@@ -14,7 +14,7 @@ TEST(ToList, List2List) ...@@ -14,7 +14,7 @@ TEST(ToList, List2List)
src.push_back(300); src.push_back(300);
auto rng = from(src); auto rng = from(src);
auto dst = rng.toList(); auto dst = rng.toStdList();
EXPECT_EQ(dst,src); EXPECT_EQ(dst,src);
} }
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
using namespace boolinq; using namespace boolinq;
TEST(ToSet, Vector2Set) TEST(ToStdSet, Vector2Set)
{ {
std::vector<int> src; std::vector<int> src;
src.push_back(1); src.push_back(1);
...@@ -16,7 +16,7 @@ TEST(ToSet, Vector2Set) ...@@ -16,7 +16,7 @@ TEST(ToSet, Vector2Set)
src.push_back(2); src.push_back(2);
auto rng = from(src); auto rng = from(src);
auto dst = rng.toSet(); auto dst = rng.toStdSet();
EXPECT_EQ(3U, dst.size()); EXPECT_EQ(3U, dst.size());
EXPECT_NE(dst.end(), dst.find(1)); EXPECT_NE(dst.end(), dst.find(1));
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
using namespace boolinq; using namespace boolinq;
TEST(ToVector, Vector2Vector) TEST(ToStdVector, Vector2Vector)
{ {
std::vector<int> src; std::vector<int> src;
src.push_back(100); src.push_back(100);
...@@ -14,7 +14,7 @@ TEST(ToVector, Vector2Vector) ...@@ -14,7 +14,7 @@ TEST(ToVector, Vector2Vector)
src.push_back(300); src.push_back(300);
auto rng = from(src); auto rng = from(src);
auto dst = rng.toVector(); auto dst = rng.toStdVector();
EXPECT_EQ(dst,src); EXPECT_EQ(dst,src);
} }
...@@ -10,7 +10,7 @@ using namespace boolinq; ...@@ -10,7 +10,7 @@ using namespace boolinq;
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
TEST(UnbitsRange, OneByteDefault) TEST(Unbits, OneByteDefault)
{ {
int src[] = {1,0,1,0,1,0,1,0}; int src[] = {1,0,1,0,1,0,1,0};
int ans[] = {0xAA}; int ans[] = {0xAA};
...@@ -21,24 +21,24 @@ TEST(UnbitsRange, OneByteDefault) ...@@ -21,24 +21,24 @@ TEST(UnbitsRange, OneByteDefault)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(UnbitsRange, OneByteHL) TEST(Unbits, OneByteHL)
{ {
int src[] = {1,0,1,0,1,0,1,0}; int src[] = {1,0,1,0,1,0,1,0};
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);
} }
TEST(UnbitsRange, OneByteLH) TEST(Unbits, OneByteLH)
{ {
int src[] = {0,1,0,1,0,1,0,1}; int src[] = {0,1,0,1,0,1,0,1};
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);
} }
...@@ -10,7 +10,7 @@ using namespace boolinq; ...@@ -10,7 +10,7 @@ using namespace boolinq;
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
TEST(UnbytesRange, OneIntDefault) TEST(Unbytes, OneIntDefault)
{ {
unsigned char src[] = {0xAA,0xBB,0xCC,0xDD}; unsigned char src[] = {0xAA,0xBB,0xCC,0xDD};
unsigned ans[] = {0xDDCCBBAA}; unsigned ans[] = {0xDDCCBBAA};
...@@ -21,31 +21,31 @@ TEST(UnbytesRange, OneIntDefault) ...@@ -21,31 +21,31 @@ TEST(UnbytesRange, OneIntDefault)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(UnbytesRange, OneIntFL) TEST(Unbytes, OneIntFL)
{ {
unsigned char src[] = {0xAA,0xBB,0xCC,0xDD}; unsigned char src[] = {0xAA,0xBB,0xCC,0xDD};
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);
} }
TEST(UnbytesRange, OneIntLF) TEST(Unbytes, OneIntLF)
{ {
unsigned char src[] = {0xAA,0xBB,0xCC,0xDD}; unsigned char src[] = {0xAA,0xBB,0xCC,0xDD};
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);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
TEST(UnbytesRange, TwoIntsDefault) TEST(Unbytes, TwoIntsDefault)
{ {
unsigned char src[] = unsigned char src[] =
{ {
...@@ -60,7 +60,7 @@ TEST(UnbytesRange, TwoIntsDefault) ...@@ -60,7 +60,7 @@ TEST(UnbytesRange, TwoIntsDefault)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(UnbytesRange, TwoIntsFL) TEST(Unbytes, TwoIntsFL)
{ {
unsigned char src[] = unsigned char src[] =
{ {
...@@ -70,12 +70,12 @@ TEST(UnbytesRange, TwoIntsFL) ...@@ -70,12 +70,12 @@ 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);
} }
TEST(UnbytesRange, TwoIntsLF) TEST(Unbytes, TwoIntsLF)
{ {
unsigned char src[] = unsigned char src[] =
{ {
...@@ -85,19 +85,19 @@ TEST(UnbytesRange, TwoIntsLF) ...@@ -85,19 +85,19 @@ 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);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
TEST(UnbytesRange, EmptyDefault) TEST(Unbytes, EmptyDefault)
{ {
std::vector<unsigned char> src; std::vector<unsigned char> src;
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.next(), LinqEndException);
} }
...@@ -10,20 +10,20 @@ using namespace boolinq; ...@@ -10,20 +10,20 @@ using namespace boolinq;
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
TEST(WhereRange, IntOdd) TEST(Where, IntOdd)
{ {
int src[] = {1,2,3,4,5,6}; int src[] = {1,2,3,4,5,6};
int ans[] = {1, 3, 5}; int ans[] = {1, 3, 5};
auto rng = from(src); auto rng = from(src);
auto dst = rng.where([](int a){return a%2 == 1;}); auto dst = rng.where([](int a){return a%2 == 1;});
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
TEST(WhereRange, FirstLetterFront) TEST(Where, FirstLetterFront)
{ {
std::string src[] = std::string src[] =
{ {
...@@ -42,13 +42,13 @@ TEST(WhereRange, FirstLetterFront) ...@@ -42,13 +42,13 @@ TEST(WhereRange, FirstLetterFront)
auto rng = from(src); auto rng = from(src);
auto dst = rng.where([](std::string a){return a[0] == 'a';}); auto dst = rng.where([](std::string a){return a[0] == 'a';});
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
TEST(WhereRange, NameAgeLess) TEST(Where, NameAgeLess)
{ {
struct NameAge struct NameAge
{ {
...@@ -73,24 +73,24 @@ TEST(WhereRange, NameAgeLess) ...@@ -73,24 +73,24 @@ TEST(WhereRange, NameAgeLess)
auto rng = from(src); auto rng = from(src);
auto dst = rng.where([](const NameAge & a){return a.age < 18;}); auto dst = rng.where([](const NameAge & a){return a.age < 18;});
CheckRangeEqArray(dst, ans, [](const NameAge & a){return a.name;}); CheckRangeEqArray(dst, ans, [](const NameAge & a){return a.name;});
} }
////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
TEST(WhereRange, MayToOne) TEST(Where, MayToOne)
{ {
int src[] = {0,1,2}; int src[] = {0,1,2};
int ans[] = {1}; int ans[] = {1};
auto rng = from(src); auto rng = from(src);
auto dst = rng.where([](int a){return a == 1;}); auto dst = rng.where([](int a){return a == 1;});
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(WhereRange, OneToOne) TEST(Where, OneToOne)
{ {
int src[] = {5}; int src[] = {5};
int ans[] = {5}; int ans[] = {5};
...@@ -101,32 +101,32 @@ TEST(WhereRange, OneToOne) ...@@ -101,32 +101,32 @@ TEST(WhereRange, OneToOne)
CheckRangeEqArray(dst, ans); CheckRangeEqArray(dst, ans);
} }
TEST(WhereRange, ManyToZero) TEST(Where, ManyToZero)
{ {
int src[] = {0,1,2}; int src[] = {0,1,2};
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.next(), LinqEndException);
} }
TEST(WhereRange, OneToZero) TEST(Where, OneToZero)
{ {
int src[] = {5}; int src[] = {5};
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.next(), LinqEndException);
} }
TEST(WhereRange, ZeroToZero) TEST(Where, ZeroToZero)
{ {
std::vector<int> src; std::vector<int> src;
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.next(), LinqEndException);
} }
#include <gtest/gtest.h> #include <gtest/gtest.h>
////////////////////////////////////////////////////////////////
/*
template<class R, class T>
R find(R r, T value)
{
for (; !r.empty(); r.popFront())
if (value == r.front()) break;
return r;
}
template<class R, class T>
R find_end(R r, T value)
{
return retro(find(retro(r), value));
}
*/
////////////////////////////////////////////////////////////////
int main(int argc, char * argv[]) int main(int argc, char * argv[])
{ {
::testing::InitGoogleMock(&argc, argv); ::testing::InitGoogleMock(&argc, argv);
......
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