From 4925b4a2c31abca5ad5b934a678b458fd297ccc2 Mon Sep 17 00:00:00 2001 From: Lennard Rohs Date: Sat, 29 Jan 2022 22:39:57 +0100 Subject: [PATCH 1/2] added boolingq::mut_from and modified for each to be able to mutate --- include/boolinq/boolinq.h | 625 ++++++++++++++++++++++---------------- test/ForEachTest.cpp | 57 ++++ 2 files changed, 422 insertions(+), 260 deletions(-) diff --git a/include/boolinq/boolinq.h b/include/boolinq/boolinq.h index aece8de..bd85ebb 100644 --- a/include/boolinq/boolinq.h +++ b/include/boolinq/boolinq.h @@ -32,6 +32,7 @@ namespace boolinq { // struct LinqEndException {}; + struct LinqNonMutableException {}; enum BytesDirection { BytesFirstToLast, @@ -45,17 +46,22 @@ namespace boolinq { template class Linq { - std::function nextFunc; + std::function nextFunc; + std::function ref_nextFunc; S storage; - + bool isMutable; public: typedef T value_type; + Linq() : nextFunc(), storage() { } - Linq(S storage, std::function nextFunc) : nextFunc(nextFunc), storage(storage) + Linq(S storage, std::function nextFunc) : nextFunc(nextFunc), ref_nextFunc([](S&) {return nullptr; }), storage(storage),isMutable(false) + { + } + Linq(S storage, std::function ref_nextFunc) : storage(storage), nextFunc([ref_nextFunc](S& s) {return *(T*)(ref_nextFunc(s)); }), ref_nextFunc(ref_nextFunc), isMutable(true) { } @@ -64,6 +70,12 @@ namespace boolinq { return nextFunc(storage); } + T* ref_next() + { + if (!isMutable) throw LinqNonMutableException(); + return (T*)ref_nextFunc(storage); + } + void for_each_i(std::function apply) const { Linq linq = *this; @@ -72,29 +84,49 @@ namespace boolinq { apply(linq.next(), i); } } - catch (LinqEndException &) {} + catch (LinqEndException&) {} + } + void mut_for_each_i(std::function apply) const + { + Linq linq = *this; + try { + for (int i = 0; ; i++) { + apply(*linq.ref_next(), i); + } + } + catch (LinqEndException&) {} } - void for_each(std::function apply) const + void for_each(std::function apply) const { - return for_each_i([apply](T value, int) { return apply(value); }); + if(isMutable) + return mut_for_each_i([apply](T& value, int) { return apply(value); }); + else + return for_each_i([apply](T value, int) { return apply(value); }); + } + template::value>::value> + void for_each(std::function apply) const + { + return for_each_i([apply](T value, int) { return apply(value); }); + } Linq, int>, T> where_i(std::function filter) const { return Linq, int>, T>( std::make_tuple(*this, 0), - [filter](std::tuple, int> &tuple) { - Linq &linq = std::get<0>(tuple); - int &index = std::get<1>(tuple); - - while (true) { - T ret = linq.next(); - if (filter(ret, index++)) { - return ret; - } + [filter](std::tuple, int>& tuple) { + Linq& linq = std::get<0>(tuple); + int& index = std::get<1>(tuple); + + while (true) { + T ret = linq.next(); + if (filter(ret, index++)) { + return ret; } } + } ); } @@ -137,22 +169,22 @@ namespace boolinq { { return Linq, int, bool>, T>( std::make_tuple(*this, 0, false), - [predicate](std::tuple, int, bool> &tuple) { - Linq &linq = std::get<0>(tuple); - int &index = std::get<1>(tuple); - bool &flag = std::get<2>(tuple); + [predicate](std::tuple, int, bool>& tuple) { + Linq& linq = std::get<0>(tuple); + int& index = std::get<1>(tuple); + bool& flag = std::get<2>(tuple); - if (flag) { - return linq.next(); - } - while (true) { - T ret = linq.next(); - if (!predicate(ret, index++)) { - flag = true; - return ret; - } + if (flag) { + return linq.next(); + } + while (true) { + T ret = linq.next(); + if (!predicate(ret, index++)) { + flag = true; + return ret; } } + } ); } @@ -166,26 +198,26 @@ namespace boolinq { { return Linq, std::vector, int>, T>( std::make_tuple(*this, std::vector{ newValues... }, -1), - [](std::tuple, std::vector, int> &tuple) { - Linq &linq = std::get<0>(tuple); - std::vector &values = std::get<1>(tuple); - int &index = std::get<2>(tuple); - - if (index == -1) { - try { - return linq.next(); - } - catch (LinqEndException &) { - index = 0; - } - } + [](std::tuple, std::vector, int>& tuple) { + Linq& linq = std::get<0>(tuple); + std::vector& values = std::get<1>(tuple); + int& index = std::get<2>(tuple); - if (index < values.size()) { - return values[index++]; + if (index == -1) { + try { + return linq.next(); + } + catch (LinqEndException&) { + index = 0; } + } - throw LinqEndException(); + if (index < values.size()) { + return values[index++]; } + + throw LinqEndException(); + } ); } @@ -194,16 +226,16 @@ namespace boolinq { { return Linq, std::vector, int>, T>( std::make_tuple(*this, std::vector{ newValues... }, 0), - [](std::tuple, std::vector, int> &tuple) { - Linq &linq = std::get<0>(tuple); - std::vector &values = std::get<1>(tuple); - int &index = std::get<2>(tuple); + [](std::tuple, std::vector, int>& tuple) { + Linq& linq = std::get<0>(tuple); + std::vector& values = std::get<1>(tuple); + int& index = std::get<2>(tuple); - if (index < values.size()) { - return values[index++]; - } - return linq.next(); + if (index < values.size()) { + return values[index++]; } + return linq.next(); + } ); } @@ -212,12 +244,12 @@ namespace boolinq { { return Linq, int>, _TRet>( std::make_tuple(*this, 0), - [apply](std::tuple, int> &tuple) { - Linq &linq = std::get<0>(tuple); - int &index = std::get<1>(tuple); + [apply](std::tuple, int>& tuple) { + Linq& linq = std::get<0>(tuple); + int& index = std::get<1>(tuple); - return apply(linq.next(), index++); - } + return apply(linq.next(), index++); + } ); } @@ -234,23 +266,23 @@ namespace boolinq { } template - Linq, Linq, bool>, T> concat(const Linq & rhs) const + Linq, Linq, bool>, T> concat(const Linq& rhs) const { return Linq, Linq, bool>, T>( std::make_tuple(*this, rhs, false), - [](std::tuple, Linq, bool> &tuple){ - Linq &first = std::get<0>(tuple); - Linq &second = std::get<1>(tuple); - bool &flag = std::get<2>(tuple); - - if (!flag) { - try { - return first.next(); - } - catch (LinqEndException &) {} + [](std::tuple, Linq, bool>& tuple) { + Linq& first = std::get<0>(tuple); + Linq& second = std::get<1>(tuple); + bool& flag = std::get<2>(tuple); + + if (!flag) { + try { + return first.next(); } - return second.next(); + catch (LinqEndException&) {} } + return second.next(); + } ); } @@ -259,29 +291,29 @@ namespace boolinq { typename _TRet = typename priv::result_of::type, typename _TRetVal = typename _TRet::value_type > - Linq, _TRet, int, bool>, _TRetVal> selectMany_i(F apply) const + Linq, _TRet, int, bool>, _TRetVal> selectMany_i(F apply) const { return Linq, _TRet, int, bool>, _TRetVal>( std::make_tuple(*this, _TRet(), 0, true), - [apply](std::tuple, _TRet, int, bool> &tuple) { - Linq &linq = std::get<0>(tuple); - _TRet ¤t = 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; - } + [apply](std::tuple, _TRet, int, bool>& tuple) { + Linq& 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; } } + } ); } @@ -290,7 +322,7 @@ namespace boolinq { typename _TRet = typename priv::result_of::type, typename _TRetVal = typename _TRet::value_type > - Linq, _TRet, int, bool>, _TRetVal> selectMany(F apply) const + Linq, _TRet, int, bool>, _TRetVal> selectMany(F apply) const { return selectMany_i([apply](T value, int /*index*/) { return apply(value); }); } @@ -300,24 +332,24 @@ namespace boolinq { typename _TKey = typename priv::result_of::type, typename _TValue = Linq, int>, T> // where(predicate) > - Linq, Linq, std::unordered_set<_TKey> >, std::pair<_TKey, _TValue> > groupBy(F apply) const + Linq, Linq, std::unordered_set<_TKey> >, std::pair<_TKey, _TValue> > groupBy(F apply) const { return Linq, Linq, std::unordered_set<_TKey> >, std::pair<_TKey, _TValue> >( std::make_tuple(*this, *this, std::unordered_set<_TKey>()), - [apply](std::tuple, Linq, std::unordered_set<_TKey> > &tuple){ - Linq &linq = std::get<0>(tuple); - Linq &linqCopy = std::get<1>(tuple); - std::unordered_set<_TKey> &set = std::get<2>(tuple); - - while (true) { - _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; - })); - } + [apply](std::tuple, Linq, std::unordered_set<_TKey> >& tuple) { + Linq& linq = std::get<0>(tuple); + Linq& linqCopy = std::get<1>(tuple); + std::unordered_set<_TKey>& set = std::get<2>(tuple); + + while (true) { + _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; + })); } } + } ); } @@ -326,17 +358,17 @@ namespace boolinq { { return Linq, std::unordered_set<_TRet> >, T>( std::make_tuple(*this, std::unordered_set<_TRet>()), - [transform](std::tuple, std::unordered_set<_TRet> > &tuple) { - Linq &linq = std::get<0>(tuple); - std::unordered_set<_TRet> &set = std::get<1>(tuple); - - while (true) { - T value = linq.next(); - if (set.insert(transform(value)).second) { - return value; - } + [transform](std::tuple, std::unordered_set<_TRet> >& tuple) { + Linq& linq = std::get<0>(tuple); + std::unordered_set<_TRet>& set = std::get<1>(tuple); + + while (true) { + T value = linq.next(); + if (set.insert(transform(value)).second) { + return value; } } + } ); } @@ -349,26 +381,26 @@ namespace boolinq { Linq, _TIter, bool>, T> orderBy(F transform) const { std::vector items = toStdVector(); - std::sort(items.begin(), items.end(), [transform](const T &a, const T &b) { + std::sort(items.begin(), items.end(), [transform](const T& a, const T& b) { return transform(a) < transform(b); }); return Linq, _TIter, bool>, T>( std::make_tuple(items, _TIter(), false), - [](std::tuple, _TIter, bool> &tuple) { - std::vector &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++); + [](std::tuple, _TIter, bool>& tuple) { + std::vector& 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++); + } ); } @@ -382,20 +414,20 @@ namespace boolinq { { return Linq, _TIter, bool>, T>( std::make_tuple(toStdList(), _TIter(), false), - [](std::tuple, _TIter, bool> &tuple) { - std::list &list = std::get<0>(tuple); - _TIter &it = std::get<1>(tuple); - bool &flag = std::get<2>(tuple); - - if (!flag) { - flag = true; - it = list.crbegin(); - } - if (it == list.crend()) { - throw LinqEndException(); - } - return *(it++); + [](std::tuple, _TIter, bool>& tuple) { + std::list& list = std::get<0>(tuple); + _TIter& it = std::get<1>(tuple); + bool& flag = std::get<2>(tuple); + + if (!flag) { + flag = true; + it = list.crbegin(); + } + if (it == list.crend()) { + throw LinqEndException(); } + return *(it++); + } ); } @@ -410,7 +442,7 @@ namespace boolinq { start = accumulate(start, linq.next()); } } - catch (LinqEndException &) {} + catch (LinqEndException&) {} return start; } @@ -457,7 +489,7 @@ namespace boolinq { return where(predicate).count(); } - int count(const T &item) const + int count(const T& item) const { return count([item](T value) { return item == value; }); } @@ -474,7 +506,7 @@ namespace boolinq { } } } - catch (LinqEndException &) {} + catch (LinqEndException&) {} return false; } @@ -493,7 +525,7 @@ namespace boolinq { return all([](T value) { return static_cast(value); }); } - bool contains(const T &item) const + bool contains(const T& item) const { return any([&item](T value) { return value == item; }); } @@ -506,7 +538,8 @@ namespace boolinq { for_each_i([accumulate, &result](T value, int i) { if (i == 0) { result = value; - } else { + } + else { result = accumulate(result, value); } }); @@ -516,7 +549,7 @@ namespace boolinq { template T max(F transform) const { - return elect([transform](const T &a, const T &b) { + return elect([transform](const T& a, const T& b) { return (transform(a) < transform(b)) ? b : a; }); } @@ -529,7 +562,7 @@ namespace boolinq { template T min(F transform) const { - return elect([transform](const T &a, const T &b) { + return elect([transform](const T& a, const T& b) { return (transform(a) < transform(b)) ? a : b; }); } @@ -561,7 +594,7 @@ namespace boolinq { try { return where(predicate).next(); } - catch (LinqEndException &) {} + catch (LinqEndException&) {} return defaultValue; } @@ -570,7 +603,7 @@ namespace boolinq { try { return Linq(*this).next(); } - catch (LinqEndException &) {} + catch (LinqEndException&) {} return defaultValue; } @@ -661,27 +694,27 @@ namespace boolinq { { return Linq, BytesDirection, T, int>, int>( std::make_tuple(*this, direction, T(), sizeof(T)), - [](std::tuple, BytesDirection, T, int> &tuple) { - Linq &linq = std::get<0>(tuple); - BytesDirection &bytesDirection = std::get<1>(tuple); - T &value = std::get<2>(tuple); - int &index = std::get<3>(tuple); - - if (index == sizeof(T)) { - value = linq.next(); - index = 0; - } + [](std::tuple, BytesDirection, T, int>& tuple) { + Linq& linq = std::get<0>(tuple); + BytesDirection& bytesDirection = std::get<1>(tuple); + T& value = std::get<2>(tuple); + int& index = std::get<3>(tuple); + + if (index == sizeof(T)) { + value = linq.next(); + index = 0; + } - unsigned char *ptr = reinterpret_cast(&value); + unsigned char* ptr = reinterpret_cast(&value); - int byteIndex = index; - if (bytesDirection == BytesLastToFirst) { - byteIndex = sizeof(T) - 1 - byteIndex; - } - - index++; - return ptr[byteIndex]; + int byteIndex = index; + if (bytesDirection == BytesLastToFirst) { + byteIndex = sizeof(T) - 1 - byteIndex; } + + index++; + return ptr[byteIndex]; + } ); } @@ -690,25 +723,25 @@ namespace boolinq { { return Linq, BytesDirection, int>, TRet>( std::make_tuple(*this, direction, 0), - [](std::tuple, BytesDirection, int> &tuple) { - Linq &linq = std::get<0>(tuple); - BytesDirection &bytesDirection = std::get<1>(tuple); - // int &index = std::get<2>(tuple); - - TRet value; - unsigned char *ptr = reinterpret_cast(&value); + [](std::tuple, BytesDirection, int>& tuple) { + Linq& linq = std::get<0>(tuple); + BytesDirection& bytesDirection = std::get<1>(tuple); + // int &index = std::get<2>(tuple); - for (int i = 0; i < sizeof(TRet); i++) { - int byteIndex = i; - if (bytesDirection == BytesLastToFirst) { - byteIndex = sizeof(TRet) - 1 - byteIndex; - } + TRet value; + unsigned char* ptr = reinterpret_cast(&value); - ptr[byteIndex] = linq.next(); + for (int i = 0; i < sizeof(TRet); i++) { + int byteIndex = i; + if (bytesDirection == BytesLastToFirst) { + byteIndex = sizeof(TRet) - 1 - byteIndex; } - return value; + ptr[byteIndex] = linq.next(); } + + return value; + } ); } @@ -716,33 +749,33 @@ namespace boolinq { { return Linq, BytesDirection, BitsDirection, T, int>, int>( std::make_tuple(*this, bytesDir, bitsDir, T(), sizeof(T) * CHAR_BIT), - [](std::tuple, BytesDirection, BitsDirection, T, int> &tuple) { - Linq &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(&value); + [](std::tuple, BytesDirection, BitsDirection, T, int>& tuple) { + Linq& 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; + } - int byteIndex = index / CHAR_BIT; - if (bytesDirection == BytesLastToFirst) { - byteIndex = sizeof(T) - 1 - byteIndex; - } + unsigned char* ptr = reinterpret_cast(&value); - int bitIndex = index % CHAR_BIT; - if (bitsDirection == BitsHighToLow) { - bitIndex = CHAR_BIT - 1 - bitIndex; - } + int byteIndex = index / CHAR_BIT; + if (bytesDirection == BytesLastToFirst) { + byteIndex = sizeof(T) - 1 - byteIndex; + } - index++; - return (ptr[byteIndex] >> bitIndex) & 1; + int bitIndex = index % CHAR_BIT; + if (bitsDirection == BitsHighToLow) { + bitIndex = CHAR_BIT - 1 - bitIndex; } + + index++; + return (ptr[byteIndex] >> bitIndex) & 1; + } ); } @@ -751,80 +784,150 @@ namespace boolinq { { return Linq, BytesDirection, BitsDirection, int>, TRet>( std::make_tuple(*this, bytesDir, bitsDir, 0), - [](std::tuple, BytesDirection, BitsDirection, int> &tuple) { - Linq &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(&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; + [](std::tuple, BytesDirection, BitsDirection, int>& tuple) { + Linq& 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(&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; } - return value; + ptr[byteIndex] &= ~(1 << bitIndex); + ptr[byteIndex] |= bool(linq.next()) << bitIndex; } + + return value; + } ); } }; template - std::ostream &operator<<(std::ostream &stream, Linq linq) + std::ostream& operator<<(std::ostream& stream, Linq linq) { try { while (true) { stream << linq.next() << ' '; } } - catch (LinqEndException &) {} + catch (LinqEndException&) {} return stream; } + //////////////////////////////////////////////////////////////// + // mut_from Creators + //////////////////////////////////////////////////////////////// + + + template + Linq, typename std::iterator_traits::value_type> mut_from(const T& begin, const T& end) + { + return Linq, typename std::iterator_traits::value_type>( + std::make_pair(begin, end), + [](std::pair& pair) { + if (pair.first == pair.second) { + throw LinqEndException(); + } + return ((void*)&(*(pair.first++))); + } + ); + } + + template + Linq, typename std::iterator_traits::value_type> mut_from(const T& it, int n) + { + return mut_from(it, it + n); + } + + template + Linq, T> mut_from(T(&array)[N]) + { + return mut_from((const T*)(&array), (const T*)(&array) + N); + } + + template class TV, typename TT> + auto mut_from(const TV& container) + -> decltype(mut_from(container.cbegin(), container.cend())) + { + return mut_from(container.cbegin(), container.cend()); + } + + // std::list, std::vector, std::dequeue + template class TV, typename TT, typename TU> + auto mut_from(const TV& container) + -> decltype(mut_from(container.cbegin(), container.cend())) + { + return mut_from(container.cbegin(), container.cend()); + } + + // std::set + template class TV, typename TT, typename TS, typename TU> + auto mut_from(const TV& container) + -> decltype(mut_from(container.cbegin(), container.cend())) + { + return mut_from(container.cbegin(), container.cend()); + } + + // std::map + template class TV, typename TK, typename TT, typename TS, typename TU> + auto mut_from(const TV& container) + -> decltype(mut_from(container.cbegin(), container.cend())) + { + return mut_from(container.cbegin(), container.cend()); + } + + // std::array + template class TV, typename TT, size_t TL> + auto mut_from(const TV& container) + -> decltype(mut_from(container.cbegin(), container.cend())) + { + return mut_from(container.cbegin(), container.cend()); + } + //////////////////////////////////////////////////////////////// // Linq Creators //////////////////////////////////////////////////////////////// template - Linq, typename std::iterator_traits::value_type> from(const T & begin, const T & end) + Linq, typename std::iterator_traits::value_type> from(const T& begin, const T& end) { return Linq, typename std::iterator_traits::value_type>( std::make_pair(begin, end), - [](std::pair &pair) { - if (pair.first == pair.second) { - throw LinqEndException(); - } - return *(pair.first++); + [](std::pair& pair) { + if (pair.first == pair.second) { + throw LinqEndException(); } + return *(pair.first++); + } ); } template - Linq, typename std::iterator_traits::value_type> from(const T & it, int n) + Linq, typename std::iterator_traits::value_type> from(const T& it, int n) { return from(it, it + n); } template - Linq, T> from(T (&array)[N]) + Linq, T> from(T(&array)[N]) { - return from((const T *)(&array), (const T *)(&array) + N); + return from((const T*)(&array), (const T*)(&array) + N); } template class TV, typename TT> - auto from(const TV & container) + auto from(const TV& container) -> decltype(from(container.cbegin(), container.cend())) { return from(container.cbegin(), container.cend()); @@ -832,7 +935,7 @@ namespace boolinq { // std::list, std::vector, std::dequeue template class TV, typename TT, typename TU> - auto from(const TV & container) + auto from(const TV& container) -> decltype(from(container.cbegin(), container.cend())) { return from(container.cbegin(), container.cend()); @@ -840,7 +943,7 @@ namespace boolinq { // std::set template class TV, typename TT, typename TS, typename TU> - auto from(const TV & container) + auto from(const TV& container) -> decltype(from(container.cbegin(), container.cend())) { return from(container.cbegin(), container.cend()); @@ -848,7 +951,7 @@ namespace boolinq { // std::map template class TV, typename TK, typename TT, typename TS, typename TU> - auto from(const TV & container) + auto from(const TV& container) -> decltype(from(container.cbegin(), container.cend())) { return from(container.cbegin(), container.cend()); @@ -856,42 +959,44 @@ namespace boolinq { // std::array template class TV, typename TT, size_t TL> - auto from(const TV & container) + auto from(const TV& container) -> decltype(from(container.cbegin(), container.cend())) { return from(container.cbegin(), container.cend()); } + + template - Linq, T> repeat(const T & value, int count) { + Linq, T> repeat(const T& value, int count) { return Linq, T>( std::make_pair(value, count), - [](std::pair &pair) { - if (pair.second > 0) { - pair.second--; - return pair.first; - } - throw LinqEndException(); + [](std::pair& pair) { + if (pair.second > 0) { + pair.second--; + return pair.first; } + throw LinqEndException(); + } ); } template - Linq, T> range(const T & start, const T & end, const T & step) { + Linq, T> range(const T& start, const T& end, const T& step) { return Linq, T>( std::make_tuple(start, end, step), - [](std::tuple &tuple) { - T &start = std::get<0>(tuple); - T &end = std::get<1>(tuple); - T &step = std::get<2>(tuple); - - T value = start; - if (value < end) { - start += step; - return value; - } - throw LinqEndException(); + [](std::tuple& tuple) { + T& start = std::get<0>(tuple); + T& end = std::get<1>(tuple); + T& step = std::get<2>(tuple); + + T value = start; + if (value < end) { + start += step; + return value; } + throw LinqEndException(); + } ); } -} +} \ No newline at end of file diff --git a/test/ForEachTest.cpp b/test/ForEachTest.cpp index fa3955f..2f351bb 100644 --- a/test/ForEachTest.cpp +++ b/test/ForEachTest.cpp @@ -46,3 +46,60 @@ TEST(ForEach, ThreeIntsSum) EXPECT_EQ(60, sum); } + + + +TEST(ForEach, Mutation_Struct) +{ + struct _Human { + + std::string name; + int age; + + std::string toString() { + + std:: stringstream s; + s << "- name : " << name << " age : " << age << " -"; + return s.str(); + } + + }; + _Human items[4] = { {"Albert",56}, + {"Heinrich",64}, + {"Renate",75}, + {"Anneliese",45} }; + + mut_from(items).for_each([](_Human& human) mutable {human.age += 1; }); + + EXPECT_EQ(items[0].age, 57); + EXPECT_EQ(items[1].age, 65); + EXPECT_EQ(items[2].age, 76); + EXPECT_EQ(items[3].age, 46); +} +TEST(ForEach, NonMutable_Struct) +{ + struct _Human { + + std::string name; + int age; + + std::string toString() { + + std::stringstream s; + s << "- name : " << name << " age : " << age << " -"; + return s.str(); + } + + }; + _Human items[4] = { {"Albert",56}, + {"Heinrich",64}, + {"Renate",75}, + {"Anneliese",45} }; + + from(items).for_each([](_Human& human) mutable {human.age += 1; }); + + EXPECT_EQ(items[0].age, 56); + EXPECT_EQ(items[1].age, 64); + EXPECT_EQ(items[2].age, 75); + EXPECT_EQ(items[3].age, 45); +} \ No newline at end of file From 7db196a4abdb214f3962dfcba12ae7f73ef6c366 Mon Sep 17 00:00:00 2001 From: Lennard Rohs Date: Mon, 31 Jan 2022 20:41:36 +0100 Subject: [PATCH 2/2] reverted formatting changes --- include/boolinq/boolinq.h | 608 +++++++++++++++++++------------------- 1 file changed, 302 insertions(+), 306 deletions(-) diff --git a/include/boolinq/boolinq.h b/include/boolinq/boolinq.h index bd85ebb..5b63fb2 100644 --- a/include/boolinq/boolinq.h +++ b/include/boolinq/boolinq.h @@ -46,22 +46,23 @@ namespace boolinq { template class Linq { - std::function nextFunc; - std::function ref_nextFunc; + + std::function nextFunc; + std::function ref_nextFunc; S storage; bool isMutable; + public: typedef T value_type; - Linq() : nextFunc(), storage() { } - Linq(S storage, std::function nextFunc) : nextFunc(nextFunc), ref_nextFunc([](S&) {return nullptr; }), storage(storage),isMutable(false) + Linq(S storage, std::function nextFunc) : nextFunc(nextFunc), ref_nextFunc([](S &) {return nullptr; }), storage(storage), isMutable(false) { } - Linq(S storage, std::function ref_nextFunc) : storage(storage), nextFunc([ref_nextFunc](S& s) {return *(T*)(ref_nextFunc(s)); }), ref_nextFunc(ref_nextFunc), isMutable(true) + Linq(S storage, std::function ref_nextFunc) : storage(storage), nextFunc([ref_nextFunc](S & s) {return *(T*)(ref_nextFunc(s)); }), ref_nextFunc(ref_nextFunc), isMutable(true) { } @@ -84,9 +85,10 @@ namespace boolinq { apply(linq.next(), i); } } - catch (LinqEndException&) {} + catch (LinqEndException &) {} } - void mut_for_each_i(std::function apply) const + + void mut_for_each_i(std::function apply) const { Linq linq = *this; try { @@ -97,36 +99,38 @@ namespace boolinq { catch (LinqEndException&) {} } - void for_each(std::function apply) const + void for_each(std::function apply) const { - if(isMutable) - return mut_for_each_i([apply](T& value, int) { return apply(value); }); + if (isMutable) + return mut_for_each_i([apply](T & value, int) { return apply(value); }); else return for_each_i([apply](T value, int) { return apply(value); }); - + } + template::value>::value> + typename = std::enable_if < std::is_lvalue_reference::value,bool> = false> void for_each(std::function apply) const { return for_each_i([apply](T value, int) { return apply(value); }); } + Linq, int>, T> where_i(std::function filter) const { return Linq, int>, T>( std::make_tuple(*this, 0), - [filter](std::tuple, int>& tuple) { - Linq& linq = std::get<0>(tuple); - int& index = std::get<1>(tuple); - - while (true) { - T ret = linq.next(); - if (filter(ret, index++)) { - return ret; + [filter](std::tuple, int> &tuple) { + Linq &linq = std::get<0>(tuple); + int &index = std::get<1>(tuple); + + while (true) { + T ret = linq.next(); + if (filter(ret, index++)) { + return ret; + } } } - } ); } @@ -169,22 +173,22 @@ namespace boolinq { { return Linq, int, bool>, T>( std::make_tuple(*this, 0, false), - [predicate](std::tuple, int, bool>& tuple) { - Linq& linq = std::get<0>(tuple); - int& index = std::get<1>(tuple); - bool& flag = std::get<2>(tuple); + [predicate](std::tuple, int, bool> &tuple) { + Linq &linq = std::get<0>(tuple); + int &index = std::get<1>(tuple); + bool &flag = std::get<2>(tuple); - if (flag) { - return linq.next(); - } - while (true) { - T ret = linq.next(); - if (!predicate(ret, index++)) { - flag = true; - return ret; + if (flag) { + return linq.next(); + } + while (true) { + T ret = linq.next(); + if (!predicate(ret, index++)) { + flag = true; + return ret; + } } } - } ); } @@ -198,26 +202,26 @@ namespace boolinq { { return Linq, std::vector, int>, T>( std::make_tuple(*this, std::vector{ newValues... }, -1), - [](std::tuple, std::vector, int>& tuple) { - Linq& linq = std::get<0>(tuple); - std::vector& values = std::get<1>(tuple); - int& index = std::get<2>(tuple); - - if (index == -1) { - try { - return linq.next(); + [](std::tuple, std::vector, int> &tuple) { + Linq &linq = std::get<0>(tuple); + std::vector &values = std::get<1>(tuple); + int &index = std::get<2>(tuple); + + if (index == -1) { + try { + return linq.next(); + } + catch (LinqEndException &) { + index = 0; + } } - catch (LinqEndException&) { - index = 0; + + if (index < values.size()) { + return values[index++]; } - } - if (index < values.size()) { - return values[index++]; + throw LinqEndException(); } - - throw LinqEndException(); - } ); } @@ -226,16 +230,16 @@ namespace boolinq { { return Linq, std::vector, int>, T>( std::make_tuple(*this, std::vector{ newValues... }, 0), - [](std::tuple, std::vector, int>& tuple) { - Linq& linq = std::get<0>(tuple); - std::vector& values = std::get<1>(tuple); - int& index = std::get<2>(tuple); + [](std::tuple, std::vector, int> &tuple) { + Linq &linq = std::get<0>(tuple); + std::vector &values = std::get<1>(tuple); + int &index = std::get<2>(tuple); - if (index < values.size()) { - return values[index++]; + if (index < values.size()) { + return values[index++]; + } + return linq.next(); } - return linq.next(); - } ); } @@ -244,12 +248,12 @@ namespace boolinq { { return Linq, int>, _TRet>( std::make_tuple(*this, 0), - [apply](std::tuple, int>& tuple) { - Linq& linq = std::get<0>(tuple); - int& index = std::get<1>(tuple); + [apply](std::tuple, int> &tuple) { + Linq &linq = std::get<0>(tuple); + int &index = std::get<1>(tuple); - return apply(linq.next(), index++); - } + return apply(linq.next(), index++); + } ); } @@ -266,23 +270,23 @@ namespace boolinq { } template - Linq, Linq, bool>, T> concat(const Linq& rhs) const + Linq, Linq, bool>, T> concat(const Linq & rhs) const { return Linq, Linq, bool>, T>( std::make_tuple(*this, rhs, false), - [](std::tuple, Linq, bool>& tuple) { - Linq& first = std::get<0>(tuple); - Linq& second = std::get<1>(tuple); - bool& flag = std::get<2>(tuple); - - if (!flag) { - try { - return first.next(); + [](std::tuple, Linq, bool> &tuple){ + Linq &first = std::get<0>(tuple); + Linq &second = std::get<1>(tuple); + bool &flag = std::get<2>(tuple); + + if (!flag) { + try { + return first.next(); + } + catch (LinqEndException &) {} } - catch (LinqEndException&) {} + return second.next(); } - return second.next(); - } ); } @@ -291,29 +295,29 @@ namespace boolinq { typename _TRet = typename priv::result_of::type, typename _TRetVal = typename _TRet::value_type > - Linq, _TRet, int, bool>, _TRetVal> selectMany_i(F apply) const + Linq, _TRet, int, bool>, _TRetVal> selectMany_i(F apply) const { return Linq, _TRet, int, bool>, _TRetVal>( std::make_tuple(*this, _TRet(), 0, true), - [apply](std::tuple, _TRet, int, bool>& tuple) { - Linq& 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; + [apply](std::tuple, _TRet, int, bool> &tuple) { + Linq &linq = std::get<0>(tuple); + _TRet ¤t = 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; + } } } - } ); } @@ -322,7 +326,7 @@ namespace boolinq { typename _TRet = typename priv::result_of::type, typename _TRetVal = typename _TRet::value_type > - Linq, _TRet, int, bool>, _TRetVal> selectMany(F apply) const + Linq, _TRet, int, bool>, _TRetVal> selectMany(F apply) const { return selectMany_i([apply](T value, int /*index*/) { return apply(value); }); } @@ -332,24 +336,24 @@ namespace boolinq { typename _TKey = typename priv::result_of::type, typename _TValue = Linq, int>, T> // where(predicate) > - Linq, Linq, std::unordered_set<_TKey> >, std::pair<_TKey, _TValue> > groupBy(F apply) const + Linq, Linq, std::unordered_set<_TKey> >, std::pair<_TKey, _TValue> > groupBy(F apply) const { return Linq, Linq, std::unordered_set<_TKey> >, std::pair<_TKey, _TValue> >( std::make_tuple(*this, *this, std::unordered_set<_TKey>()), - [apply](std::tuple, Linq, std::unordered_set<_TKey> >& tuple) { - Linq& linq = std::get<0>(tuple); - Linq& linqCopy = std::get<1>(tuple); - std::unordered_set<_TKey>& set = std::get<2>(tuple); - - while (true) { - _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; - })); + [apply](std::tuple, Linq, std::unordered_set<_TKey> > &tuple){ + Linq &linq = std::get<0>(tuple); + Linq &linqCopy = std::get<1>(tuple); + std::unordered_set<_TKey> &set = std::get<2>(tuple); + + while (true) { + _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; + })); + } } } - } ); } @@ -358,17 +362,17 @@ namespace boolinq { { return Linq, std::unordered_set<_TRet> >, T>( std::make_tuple(*this, std::unordered_set<_TRet>()), - [transform](std::tuple, std::unordered_set<_TRet> >& tuple) { - Linq& linq = std::get<0>(tuple); - std::unordered_set<_TRet>& set = std::get<1>(tuple); - - while (true) { - T value = linq.next(); - if (set.insert(transform(value)).second) { - return value; + [transform](std::tuple, std::unordered_set<_TRet> > &tuple) { + Linq &linq = std::get<0>(tuple); + std::unordered_set<_TRet> &set = std::get<1>(tuple); + + while (true) { + T value = linq.next(); + if (set.insert(transform(value)).second) { + return value; + } } } - } ); } @@ -381,26 +385,26 @@ namespace boolinq { Linq, _TIter, bool>, T> orderBy(F transform) const { std::vector items = toStdVector(); - std::sort(items.begin(), items.end(), [transform](const T& a, const T& b) { + std::sort(items.begin(), items.end(), [transform](const T &a, const T &b) { return transform(a) < transform(b); }); return Linq, _TIter, bool>, T>( std::make_tuple(items, _TIter(), false), - [](std::tuple, _TIter, bool>& tuple) { - std::vector& 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(); + [](std::tuple, _TIter, bool> &tuple) { + std::vector &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++); } - return *(it++); - } ); } @@ -414,20 +418,20 @@ namespace boolinq { { return Linq, _TIter, bool>, T>( std::make_tuple(toStdList(), _TIter(), false), - [](std::tuple, _TIter, bool>& tuple) { - std::list& list = std::get<0>(tuple); - _TIter& it = std::get<1>(tuple); - bool& flag = std::get<2>(tuple); - - if (!flag) { - flag = true; - it = list.crbegin(); - } - if (it == list.crend()) { - throw LinqEndException(); + [](std::tuple, _TIter, bool> &tuple) { + std::list &list = std::get<0>(tuple); + _TIter &it = std::get<1>(tuple); + bool &flag = std::get<2>(tuple); + + if (!flag) { + flag = true; + it = list.crbegin(); + } + if (it == list.crend()) { + throw LinqEndException(); + } + return *(it++); } - return *(it++); - } ); } @@ -442,7 +446,7 @@ namespace boolinq { start = accumulate(start, linq.next()); } } - catch (LinqEndException&) {} + catch (LinqEndException &) {} return start; } @@ -489,7 +493,7 @@ namespace boolinq { return where(predicate).count(); } - int count(const T& item) const + int count(const T &item) const { return count([item](T value) { return item == value; }); } @@ -506,7 +510,7 @@ namespace boolinq { } } } - catch (LinqEndException&) {} + catch (LinqEndException &) {} return false; } @@ -525,7 +529,7 @@ namespace boolinq { return all([](T value) { return static_cast(value); }); } - bool contains(const T& item) const + bool contains(const T &item) const { return any([&item](T value) { return value == item; }); } @@ -538,8 +542,7 @@ namespace boolinq { for_each_i([accumulate, &result](T value, int i) { if (i == 0) { result = value; - } - else { + } else { result = accumulate(result, value); } }); @@ -549,7 +552,7 @@ namespace boolinq { template T max(F transform) const { - return elect([transform](const T& a, const T& b) { + return elect([transform](const T &a, const T &b) { return (transform(a) < transform(b)) ? b : a; }); } @@ -562,7 +565,7 @@ namespace boolinq { template T min(F transform) const { - return elect([transform](const T& a, const T& b) { + return elect([transform](const T &a, const T &b) { return (transform(a) < transform(b)) ? a : b; }); } @@ -594,7 +597,7 @@ namespace boolinq { try { return where(predicate).next(); } - catch (LinqEndException&) {} + catch (LinqEndException &) {} return defaultValue; } @@ -603,7 +606,7 @@ namespace boolinq { try { return Linq(*this).next(); } - catch (LinqEndException&) {} + catch (LinqEndException &) {} return defaultValue; } @@ -694,27 +697,27 @@ namespace boolinq { { return Linq, BytesDirection, T, int>, int>( std::make_tuple(*this, direction, T(), sizeof(T)), - [](std::tuple, BytesDirection, T, int>& tuple) { - Linq& linq = std::get<0>(tuple); - BytesDirection& bytesDirection = std::get<1>(tuple); - T& value = std::get<2>(tuple); - int& index = std::get<3>(tuple); - - if (index == sizeof(T)) { - value = linq.next(); - index = 0; - } + [](std::tuple, BytesDirection, T, int> &tuple) { + Linq &linq = std::get<0>(tuple); + BytesDirection &bytesDirection = std::get<1>(tuple); + T &value = std::get<2>(tuple); + int &index = std::get<3>(tuple); + + if (index == sizeof(T)) { + value = linq.next(); + index = 0; + } - unsigned char* ptr = reinterpret_cast(&value); + unsigned char *ptr = reinterpret_cast(&value); - int byteIndex = index; - if (bytesDirection == BytesLastToFirst) { - byteIndex = sizeof(T) - 1 - byteIndex; - } + int byteIndex = index; + if (bytesDirection == BytesLastToFirst) { + byteIndex = sizeof(T) - 1 - byteIndex; + } - index++; - return ptr[byteIndex]; - } + index++; + return ptr[byteIndex]; + } ); } @@ -723,25 +726,25 @@ namespace boolinq { { return Linq, BytesDirection, int>, TRet>( std::make_tuple(*this, direction, 0), - [](std::tuple, BytesDirection, int>& tuple) { - Linq& linq = std::get<0>(tuple); - BytesDirection& bytesDirection = std::get<1>(tuple); - // int &index = std::get<2>(tuple); + [](std::tuple, BytesDirection, int> &tuple) { + Linq &linq = std::get<0>(tuple); + BytesDirection &bytesDirection = std::get<1>(tuple); + // int &index = std::get<2>(tuple); - TRet value; - unsigned char* ptr = reinterpret_cast(&value); + TRet value; + unsigned char *ptr = reinterpret_cast(&value); - for (int i = 0; i < sizeof(TRet); i++) { - int byteIndex = i; - if (bytesDirection == BytesLastToFirst) { - byteIndex = sizeof(TRet) - 1 - byteIndex; + for (int i = 0; i < sizeof(TRet); i++) { + int byteIndex = i; + if (bytesDirection == BytesLastToFirst) { + byteIndex = sizeof(TRet) - 1 - byteIndex; + } + + ptr[byteIndex] = linq.next(); } - ptr[byteIndex] = linq.next(); + return value; } - - return value; - } ); } @@ -749,33 +752,33 @@ namespace boolinq { { return Linq, BytesDirection, BitsDirection, T, int>, int>( std::make_tuple(*this, bytesDir, bitsDir, T(), sizeof(T) * CHAR_BIT), - [](std::tuple, BytesDirection, BitsDirection, T, int>& tuple) { - Linq& 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; - } + [](std::tuple, BytesDirection, BitsDirection, T, int> &tuple) { + Linq &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(&value); + unsigned char *ptr = reinterpret_cast(&value); - int byteIndex = index / CHAR_BIT; - if (bytesDirection == BytesLastToFirst) { - byteIndex = sizeof(T) - 1 - byteIndex; - } + 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; - } + int bitIndex = index % CHAR_BIT; + if (bitsDirection == BitsHighToLow) { + bitIndex = CHAR_BIT - 1 - bitIndex; + } - index++; - return (ptr[byteIndex] >> bitIndex) & 1; - } + index++; + return (ptr[byteIndex] >> bitIndex) & 1; + } ); } @@ -784,124 +787,119 @@ namespace boolinq { { return Linq, BytesDirection, BitsDirection, int>, TRet>( std::make_tuple(*this, bytesDir, bitsDir, 0), - [](std::tuple, BytesDirection, BitsDirection, int>& tuple) { - Linq& 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(&value); - - for (int i = 0; i < sizeof(TRet) * CHAR_BIT; i++) { - int byteIndex = i / CHAR_BIT; - if (bytesDirection == BytesLastToFirst) { - byteIndex = sizeof(TRet) - 1 - byteIndex; + [](std::tuple, BytesDirection, BitsDirection, int> &tuple) { + Linq &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(&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; } - 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; } - - return value; - } ); } }; template - std::ostream& operator<<(std::ostream& stream, Linq linq) + std::ostream &operator<<(std::ostream &stream, Linq linq) { try { while (true) { stream << linq.next() << ' '; } } - catch (LinqEndException&) {} + catch (LinqEndException &) {} return stream; } //////////////////////////////////////////////////////////////// - // mut_from Creators + // Linq Creators //////////////////////////////////////////////////////////////// - template - Linq, typename std::iterator_traits::value_type> mut_from(const T& begin, const T& end) + Linq, typename std::iterator_traits::value_type> from(const T & begin, const T & end) { return Linq, typename std::iterator_traits::value_type>( std::make_pair(begin, end), - [](std::pair& pair) { - if (pair.first == pair.second) { - throw LinqEndException(); + [](std::pair &pair) { + if (pair.first == pair.second) { + throw LinqEndException(); + } + return *(pair.first++); } - return ((void*)&(*(pair.first++))); - } ); } template - Linq, typename std::iterator_traits::value_type> mut_from(const T& it, int n) + Linq, typename std::iterator_traits::value_type> from(const T & it, int n) { - return mut_from(it, it + n); + return from(it, it + n); } template - Linq, T> mut_from(T(&array)[N]) + Linq, T> from(T (&array)[N]) { - return mut_from((const T*)(&array), (const T*)(&array) + N); + return from((const T *)(&array), (const T *)(&array) + N); } template class TV, typename TT> - auto mut_from(const TV& container) - -> decltype(mut_from(container.cbegin(), container.cend())) + auto from(const TV & container) + -> decltype(from(container.cbegin(), container.cend())) { - return mut_from(container.cbegin(), container.cend()); + return from(container.cbegin(), container.cend()); } // std::list, std::vector, std::dequeue template class TV, typename TT, typename TU> - auto mut_from(const TV& container) - -> decltype(mut_from(container.cbegin(), container.cend())) + auto from(const TV & container) + -> decltype(from(container.cbegin(), container.cend())) { - return mut_from(container.cbegin(), container.cend()); + return from(container.cbegin(), container.cend()); } // std::set template class TV, typename TT, typename TS, typename TU> - auto mut_from(const TV& container) - -> decltype(mut_from(container.cbegin(), container.cend())) + auto from(const TV & container) + -> decltype(from(container.cbegin(), container.cend())) { - return mut_from(container.cbegin(), container.cend()); + return from(container.cbegin(), container.cend()); } // std::map template class TV, typename TK, typename TT, typename TS, typename TU> - auto mut_from(const TV& container) - -> decltype(mut_from(container.cbegin(), container.cend())) + auto from(const TV & container) + -> decltype(from(container.cbegin(), container.cend())) { - return mut_from(container.cbegin(), container.cend()); + return from(container.cbegin(), container.cend()); } // std::array template class TV, typename TT, size_t TL> - auto mut_from(const TV& container) - -> decltype(mut_from(container.cbegin(), container.cend())) + auto from(const TV & container) + -> decltype(from(container.cbegin(), container.cend())) { - return mut_from(container.cbegin(), container.cend()); + return from(container.cbegin(), container.cend()); } - //////////////////////////////////////////////////////////////// - // Linq Creators - //////////////////////////////////////////////////////////////// - template - Linq, typename std::iterator_traits::value_type> from(const T& begin, const T& end) + Linq, typename std::iterator_traits::value_type> mut_from(const T& begin, const T& end) { return Linq, typename std::iterator_traits::value_type>( std::make_pair(begin, end), @@ -909,94 +907,92 @@ namespace boolinq { if (pair.first == pair.second) { throw LinqEndException(); } - return *(pair.first++); + return ((void*)&(*(pair.first++))); } ); } template - Linq, typename std::iterator_traits::value_type> from(const T& it, int n) + Linq, typename std::iterator_traits::value_type> mut_from(const T& it, int n) { - return from(it, it + n); + return mut_from(it, it + n); } template - Linq, T> from(T(&array)[N]) + Linq, T> mut_from(T(&array)[N]) { - return from((const T*)(&array), (const T*)(&array) + N); + return mut_from((const T*)(&array), (const T*)(&array) + N); } template class TV, typename TT> - auto from(const TV& container) - -> decltype(from(container.cbegin(), container.cend())) + auto mut_from(const TV& container) + -> decltype(mut_from(container.cbegin(), container.cend())) { - return from(container.cbegin(), container.cend()); + return mut_from(container.cbegin(), container.cend()); } // std::list, std::vector, std::dequeue template class TV, typename TT, typename TU> - auto from(const TV& container) - -> decltype(from(container.cbegin(), container.cend())) + auto mut_from(const TV& container) + -> decltype(mut_from(container.cbegin(), container.cend())) { - return from(container.cbegin(), container.cend()); + return mut_from(container.cbegin(), container.cend()); } // std::set template class TV, typename TT, typename TS, typename TU> - auto from(const TV& container) - -> decltype(from(container.cbegin(), container.cend())) + auto mut_from(const TV& container) + -> decltype(mut_from(container.cbegin(), container.cend())) { - return from(container.cbegin(), container.cend()); + return mut_from(container.cbegin(), container.cend()); } // std::map template class TV, typename TK, typename TT, typename TS, typename TU> - auto from(const TV& container) - -> decltype(from(container.cbegin(), container.cend())) + auto mut_from(const TV& container) + -> decltype(mut_from(container.cbegin(), container.cend())) { - return from(container.cbegin(), container.cend()); + return mut_from(container.cbegin(), container.cend()); } // std::array template class TV, typename TT, size_t TL> - auto from(const TV& container) - -> decltype(from(container.cbegin(), container.cend())) + auto mut_from(const TV& container) + -> decltype(mut_from(container.cbegin(), container.cend())) { - return from(container.cbegin(), container.cend()); + return mut_from(container.cbegin(), container.cend()); } - - template - Linq, T> repeat(const T& value, int count) { + Linq, T> repeat(const T & value, int count) { return Linq, T>( std::make_pair(value, count), - [](std::pair& pair) { - if (pair.second > 0) { - pair.second--; - return pair.first; + [](std::pair &pair) { + if (pair.second > 0) { + pair.second--; + return pair.first; + } + throw LinqEndException(); } - throw LinqEndException(); - } ); } template - Linq, T> range(const T& start, const T& end, const T& step) { + Linq, T> range(const T & start, const T & end, const T & step) { return Linq, T>( std::make_tuple(start, end, step), - [](std::tuple& tuple) { - T& start = std::get<0>(tuple); - T& end = std::get<1>(tuple); - T& step = std::get<2>(tuple); - - T value = start; - if (value < end) { - start += step; - return value; + [](std::tuple &tuple) { + T &start = std::get<0>(tuple); + T &end = std::get<1>(tuple); + T &step = std::get<2>(tuple); + + T value = start; + if (value < end) { + start += step; + return value; + } + throw LinqEndException(); } - throw LinqEndException(); - } ); } } \ No newline at end of file