Library: a pseudo-iterator to yield just a single value
...which can be helpful when a function usually returns a somewhat dressed-up iterator, but needs to return a specific fixed value under some circumstances
This commit is contained in:
parent
7e241d9a11
commit
0682e449a3
3 changed files with 170 additions and 2 deletions
|
|
@ -575,6 +575,102 @@ namespace lib {
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of a _singleton value_ holder,
|
||||
* which discards the contained value once "iterated"
|
||||
*/
|
||||
template<typename VAL>
|
||||
class SingleValCore
|
||||
{
|
||||
typedef wrapper::ItemWrapper<VAL> Item;
|
||||
|
||||
Item theValue_;
|
||||
|
||||
public:
|
||||
SingleValCore() { } ///< passive and empty
|
||||
|
||||
SingleValCore (VAL&& something)
|
||||
: theValue_{forward<VAL> (something)}
|
||||
{ }
|
||||
|
||||
Item const&
|
||||
pipe () const
|
||||
{
|
||||
return theValue_;
|
||||
}
|
||||
|
||||
void
|
||||
advance ()
|
||||
{
|
||||
theValue_.reset();
|
||||
}
|
||||
|
||||
bool
|
||||
evaluate () const
|
||||
{
|
||||
return theValue_.isValid();
|
||||
}
|
||||
|
||||
typedef typename std::remove_reference<VAL>::type * pointer;
|
||||
typedef typename std::remove_reference<VAL>::type & reference;
|
||||
typedef typename std::remove_reference<VAL>::type value_type;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Pseudo-Iterator to yield just a single value.
|
||||
* When incremented, the value is destroyed and
|
||||
* the Iterator transitions to _exhausted state_.
|
||||
* @remark as such might look nonsensical, but proves
|
||||
* useful when a function yields an iterator, while
|
||||
* producing an explicit value in some special case.
|
||||
* @tparam VAL anything, value or reference to store
|
||||
*/
|
||||
template<class VAL>
|
||||
class SingleValIter
|
||||
: public IterTool<SingleValCore<VAL>>
|
||||
{
|
||||
using _ValHolder = SingleValCore<VAL>;
|
||||
using _IteratorImpl = IterTool<_ValHolder> ;
|
||||
|
||||
public:
|
||||
SingleValIter ()
|
||||
: _IteratorImpl{_ValHolder{}}
|
||||
{ }
|
||||
|
||||
SingleValIter (VAL&& something)
|
||||
: _IteratorImpl{_ValHolder{forward<VAL>(something)}}
|
||||
{ }
|
||||
|
||||
ENABLE_USE_IN_STD_RANGE_FOR_LOOPS (SingleValIter)
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** Build a SingleValIter: convenience free function shortcut,
|
||||
* to pick up just any value and wrap it as Lumiera Forward Iterator.
|
||||
* @return Iterator to yield the value once
|
||||
* @warning be sure to understand that we literally pick up and wrap anything
|
||||
* provided as argument. If you pass a reference, we wrap a reference.
|
||||
* If you want to wrap a copy, you have to do the copy yourself inline
|
||||
*/
|
||||
template<class VAL>
|
||||
inline auto
|
||||
singleValIterator (VAL&& something)
|
||||
{
|
||||
return SingleValIter<VAL>{forward<VAL>(something)};
|
||||
}
|
||||
|
||||
template<class VAL>
|
||||
inline auto
|
||||
singleValIterator (VAL const& ref)
|
||||
{
|
||||
return SingleValIter<VAL>{ref};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of custom processing logic.
|
||||
|
|
|
|||
|
|
@ -115,6 +115,8 @@ namespace test{
|
|||
verify_filterExtension();
|
||||
verify_filterRepetitions();
|
||||
|
||||
buildWrappedSingleElement();
|
||||
|
||||
buildTransformingIterator (source.begin());
|
||||
|
||||
verifyPullLast(source.begin());
|
||||
|
|
@ -269,6 +271,48 @@ namespace test{
|
|||
|
||||
|
||||
|
||||
/** @test wrap an arbitrary single element as pseudo-iterator */
|
||||
void
|
||||
buildWrappedSingleElement()
|
||||
{
|
||||
uint i{12};
|
||||
|
||||
auto i1 = singleValIterator(12);
|
||||
auto i2 = singleValIterator( i);
|
||||
auto i3 = singleValIterator(&i);
|
||||
|
||||
CHECK (not isnil(i1));
|
||||
CHECK (not isnil(i2));
|
||||
CHECK (not isnil(i3));
|
||||
CHECK (12 == *i1);
|
||||
CHECK (12 == *i2);
|
||||
CHECK (12 == **i3);
|
||||
|
||||
i = 23;
|
||||
CHECK (12 == *i1);
|
||||
CHECK (23 == *i2);
|
||||
CHECK (23 == **i3);
|
||||
|
||||
++i1;
|
||||
++i2;
|
||||
++i3;
|
||||
CHECK (isnil(i1));
|
||||
CHECK (isnil(i2));
|
||||
CHECK (isnil(i3));
|
||||
VERIFY_ERROR (ITER_EXHAUST, *i1 );
|
||||
VERIFY_ERROR (ITER_EXHAUST, *i2 );
|
||||
VERIFY_ERROR (ITER_EXHAUST, *i3 );
|
||||
|
||||
// assignable as any iterator..
|
||||
i1 = singleValIterator(13);
|
||||
CHECK (13 == *i1);
|
||||
|
||||
i1 = SingleValIter<int>{};
|
||||
CHECK (isnil(i1));
|
||||
}
|
||||
|
||||
|
||||
|
||||
static ulong addTwo (int i) { return i+2; }
|
||||
static int negate (int i) { return -i; }
|
||||
static int idFunc (int i) { return i; }
|
||||
|
|
|
|||
|
|
@ -4659,7 +4659,6 @@
|
|||
<icon BUILTIN="ksmiletris"/>
|
||||
<node CREATED="1509143431491" ID="ID_1535839304" MODIFIED="1509143436685" TEXT="Pfad normal weiterverarbeiten"/>
|
||||
<node CREATED="1509143437202" ID="ID_1489524396" MODIFIED="1509143442917" TEXT="aber Abstieg im Baum manipulieren"/>
|
||||
</node>
|
||||
<node CREATED="1509143453151" ID="ID_373632759" MODIFIED="1509143457604" TEXT="speziell...">
|
||||
<node CREATED="1509143459519" ID="ID_1727095948" MODIFIED="1509143468809" TEXT="existenz-Check läuft anders">
|
||||
<node CREATED="1509143492194" ID="ID_835507213" MODIFIED="1509143513852" TEXT="getType und stringvergleich"/>
|
||||
|
|
@ -4680,9 +4679,38 @@
|
|||
daß ich mich wieder mal "akademisch" verspielt habe.... :-P
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1509151268071" ID="ID_38582779" MODIFIED="1509151422017" TEXT="getChildren aufbohren">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1509151285749" ID="ID_1826645914" MODIFIED="1509151289049" TEXT="eigentlich einfach"/>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1509151289637" ID="ID_892381116" MODIFIED="1509151414927" TEXT="brauche singletonIter">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1509151296292" ID="ID_1050274308" MODIFIED="1509151411655" TEXT="liefert ein einziges Element"/>
|
||||
<node CREATED="1509151305602" ID="ID_452317335" MODIFIED="1509151411655" TEXT="als IterSource verpackt"/>
|
||||
<node CREATED="1509151309866" ID="ID_1109789284" MODIFIED="1509151411655" TEXT="sollte es als als Basis iter implementieren">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...und die IterSource dann nur über WrapIter definieren.
|
||||
</p>
|
||||
<p>
|
||||
Schichten-Prinzip...
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
<node CREATED="1509151381113" ID="ID_779657015" MODIFIED="1509151411655" TEXT="brauche ItemWrapper für beliebiges Element"/>
|
||||
<node CREATED="1509151390495" ID="ID_947844248" MODIFIED="1509151411655" TEXT="Idee: TransformIter aufbohren">
|
||||
<icon BUILTIN="help"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue