Commit a4972949 authored by Vit Babel's avatar Vit Babel

Linq Creators Improvement

1) Changed the template of 'from(const TV<TT,TL> & container)' function from int to unsigned. Only this way it accepts std::array properly for me.

2) Changed return types of some 'from()' functions to auto and used decltype() to generate the type of iterator, because there is no guarantee that iterator of collection A is A::const_iterator.

3) Added two more versions of 'from()' function, which accept std::set and std::map.

Plus: Untabyfied
parent 251feda7
...@@ -31,14 +31,14 @@ namespace boolinq ...@@ -31,14 +31,14 @@ namespace boolinq
class Enumerator class Enumerator
{ {
std::function<T(S&)> _nextObject; std::function<T(S&)> _nextObject;
S _data; S _data;
public: public:
typedef T value_type; typedef T value_type;
Enumerator(std::function<T(S&)> nextObject, S data) Enumerator(std::function<T(S&)> nextObject, S data)
: _nextObject(nextObject) : _nextObject(nextObject)
, _data(data) , _data(data)
{ {
} }
...@@ -51,13 +51,13 @@ namespace boolinq ...@@ -51,13 +51,13 @@ namespace boolinq
template<typename T, typename S> template<typename T, typename S>
std::ostream & operator << (std::ostream & stream, Enumerator<T,S> enumerator) std::ostream & operator << (std::ostream & stream, Enumerator<T,S> enumerator)
{ {
try try
{ {
for (;;) for (;;)
stream << enumerator.nextObject() << ' '; stream << enumerator.nextObject() << ' ';
} }
catch(EnumeratorEndException &) {} catch(EnumeratorEndException &) {}
return stream; return stream;
} }
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
...@@ -753,21 +753,45 @@ namespace boolinq ...@@ -753,21 +753,45 @@ namespace boolinq
return from<T>(array, array + N); return from<T>(array, array + N);
} }
// std::list, vector, dequeue
template<template<class,class> class TV, typename TT, typename TU> template<template<class,class> class TV, typename TT, typename TU>
LinqObj<Enumerator<TT,IteratorContainerPair<typename TV<TT,TU>::const_iterator,TV<TT,TU> > > > from(TV<TT,TU> & container) auto from(const TV<TT,TU> & container) -> LinqObj<Enumerator<TT,IteratorContainerPair<decltype(container.cbegin()),const TV<TT,TU> > > >
{ {
typedef IteratorContainerPair<typename TV<TT,TU>::const_iterator,TV<TT,TU> > DataType; typedef IteratorContainerPair<decltype(container.cbegin()),const TV<TT,TU> > DataType;
return Enumerator<TT,DataType>([](DataType & pair){ return Enumerator<TT,DataType>([](DataType & pair){
return (pair.first == pair.second.cend()) ? throw EnumeratorEndException() : *(pair.first++); return (pair.first == pair.second.cend()) ? throw EnumeratorEndException() : *(pair.first++);
}, DataType(container, [](const TV<TT,TU> & cont){return cont.cbegin();})); }, DataType(container, [](const TV<TT,TU> & cont){return cont.cbegin();}));
} }
template<template<class,int> class TV, typename TT, int TL> // std::set
LinqObj<Enumerator<TT,IteratorContainerPair<typename TV<TT,TL>::const_iterator,TV<TT,TL> > > > from(TV<TT,TL> & container) template<template<class,class,class> class TV, typename TT, typename TS, typename TU>
auto from(const TV<TT,TS,TU> & container) -> LinqObj<Enumerator<TT,IteratorContainerPair<decltype(container.cbegin()),const TV<TT,TS,TU> > > >
{
typedef IteratorContainerPair<decltype(container.cbegin()),const TV<TT,TS,TU> > DataType;
return Enumerator<TT,DataType>([](DataType & pair){
return (pair.first == pair.second.cend()) ? throw EnumeratorEndException() : *(pair.first++);
}, DataType(container, [](const TV<TT,TS,TU> & cont){return cont.cbegin();}));
}
// std::map
template<template<class,class,class,class> class TV, typename TK, typename TT, typename TS, typename TU>
auto from(const TV<TK,TT,TS,TU> & container) -> LinqObj<Enumerator<std::pair<TK,TT>,IteratorContainerPair<decltype(container.cbegin()),const TV<TK,TT,TS,TU> > > >
{ {
typedef IteratorContainerPair<typename TV<TT,TL>::const_iterator,TV<TT,TL> > DataType; typedef IteratorContainerPair<decltype(container.cbegin()),const TV<TK,TT,TS,TU> > DataType;
return Enumerator<std::pair<TK,TT>,DataType>([](DataType & pair){
return (pair.first == pair.second.cend()) ? throw EnumeratorEndException() : *(pair.first++);
}, DataType(container, [](const TV<TK,TT,TS,TU> & cont){return cont.cbegin();}));
}
// std::array
template<template<class,unsigned> class TV, typename TT, unsigned TL>
auto from(const TV<TT,TL> & container) -> LinqObj<Enumerator<TT,IteratorContainerPair<decltype(container.cbegin()),const TV<TT,TL> > > >
{
typedef IteratorContainerPair<decltype(container.cbegin()),const TV<TT,TL> > DataType;
return Enumerator<TT,DataType>([](DataType & pair){ return Enumerator<TT,DataType>([](DataType & pair){
return (pair.first == pair.second.cend()) ? throw EnumeratorEndException() : *(pair.first++); return (pair.first == pair.second.cend()) ? throw EnumeratorEndException() : *(pair.first++);
}, DataType(container, [](const TV<TT,TL> & cont){return cont.cbegin();})); }, DataType(container, [](const TV<TT,TL> & cont){return cont.cbegin();}));
......
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