implement IterSource adapter for STL map and hashmap
This commit is contained in:
parent
030a7d3813
commit
2a5b080dd7
3 changed files with 172 additions and 58 deletions
|
|
@ -29,6 +29,14 @@
|
|||
** a simple data source type, without needing to disclose details of
|
||||
** the implementation.
|
||||
**
|
||||
** \par Standard Adapters
|
||||
** As a complement, this header contains a generic implementation
|
||||
** of the IterSource interface by wrapping an existing Lumiera Forward Iterator.
|
||||
** Using this WrappedLumieraIterator, the details of this wrapped source iterator
|
||||
** remain opaque. To ease the use of this adapter, a selection of free functions
|
||||
** is provided, allowing to build opaque "all elements" or "all keys" iterators
|
||||
** for various STL containers.
|
||||
**
|
||||
** @see iter-adapter.hpp
|
||||
** @see itertool.hpp
|
||||
** @see iter-source-test.cpp
|
||||
|
|
@ -41,7 +49,7 @@
|
|||
|
||||
|
||||
#include "lib/iter-adapter.hpp"
|
||||
//#include "lib/bool-checkable.hpp"
|
||||
#include "lib/itertools.hpp"
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <tr1/memory>
|
||||
|
|
@ -50,7 +58,7 @@
|
|||
|
||||
|
||||
namespace lib {
|
||||
|
||||
|
||||
using std::tr1::shared_ptr;
|
||||
|
||||
|
||||
|
|
@ -70,7 +78,7 @@ namespace lib {
|
|||
class IterSource
|
||||
{
|
||||
|
||||
protected: /* == data source API for implementation == */
|
||||
protected: /* == data source API to implement == */
|
||||
|
||||
typedef TY* Pos;
|
||||
typedef shared_ptr<IterSource> DataHandle;
|
||||
|
|
@ -96,14 +104,14 @@ namespace lib {
|
|||
virtual void disconnect () { }
|
||||
|
||||
|
||||
public:
|
||||
|
||||
public:
|
||||
virtual ~IterSource() { }; ///< is ABC
|
||||
|
||||
/* == Iteration control API for IterAdapter frontend == */
|
||||
|
||||
friend bool
|
||||
hasNext (DataHandle const&, Pos const& pos) ////TICKET #410
|
||||
hasNext (DataHandle const&, Pos const& pos) ////TICKET #410
|
||||
{
|
||||
return bool(pos);
|
||||
}
|
||||
|
|
@ -111,6 +119,7 @@ namespace lib {
|
|||
friend void
|
||||
iterNext (DataHandle& source, Pos& pos)
|
||||
{
|
||||
ASSERT (source);
|
||||
source->nextResult(pos);
|
||||
}
|
||||
|
||||
|
|
@ -185,9 +194,12 @@ namespace lib {
|
|||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Standard implementation of the IterSource interface:
|
||||
* a wrapped "Lumiera Forward Iterator"
|
||||
* a wrapped "Lumiera Forward Iterator". Usually, such a wrapper instance
|
||||
* is passed to one of the IterSource's builder functions, thereby
|
||||
* erasing the specific type information of the template parameter IT
|
||||
*/
|
||||
template<class IT>
|
||||
class WrappedLumieraIterator
|
||||
|
|
@ -199,26 +211,26 @@ namespace lib {
|
|||
|
||||
IT src_;
|
||||
|
||||
Pos
|
||||
firstResult ()
|
||||
{
|
||||
if (!src_)
|
||||
return 0;
|
||||
else
|
||||
return & *src_;
|
||||
}
|
||||
|
||||
void
|
||||
nextResult (Pos& pos)
|
||||
{
|
||||
if (!pos) return;
|
||||
if (src_) ++src_;
|
||||
if (src_)
|
||||
pos = & *src_;
|
||||
else
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
Pos
|
||||
firstResult ()
|
||||
{
|
||||
if (!src_)
|
||||
return 0;
|
||||
else
|
||||
return & *src_;
|
||||
}
|
||||
|
||||
void
|
||||
nextResult (Pos& pos)
|
||||
{
|
||||
if (!pos) return;
|
||||
if (src_) ++src_;
|
||||
if (src_)
|
||||
pos = & *src_;
|
||||
else
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public:
|
||||
|
|
@ -233,48 +245,139 @@ namespace lib {
|
|||
/* === pre-defined Adapters for frequently used Containers === */
|
||||
|
||||
namespace iter_impl {
|
||||
namespace { // traits and helpers...
|
||||
|
||||
template<class CON>
|
||||
struct _SeqType
|
||||
template<class CON>
|
||||
struct _SeqT
|
||||
{
|
||||
typedef typename CON::iterator::value_type Val;
|
||||
typedef typename IterSource<Val>::iterator Iter;
|
||||
};
|
||||
|
||||
template<class MAP>
|
||||
struct _MapT
|
||||
{
|
||||
typedef typename MAP::key_type Key;
|
||||
typedef typename MAP::value_type::second_type Val;
|
||||
typedef typename IterSource<const Key>::iterator KeyIter;
|
||||
typedef typename IterSource< Val>::iterator ValIter;
|
||||
};
|
||||
|
||||
|
||||
template<class IT>
|
||||
struct _IterT
|
||||
{
|
||||
typedef typename IT::value_type Val;
|
||||
typedef typename IterSource<Val>::iterator Iter;
|
||||
};
|
||||
|
||||
template<class IT>
|
||||
struct _PairIterT
|
||||
{
|
||||
typedef typename IT::value_type PairType;
|
||||
typedef typename PairType::first_type KeyType;
|
||||
typedef typename PairType::second_type ValType;
|
||||
|
||||
typedef TransformIter<IT,KeyType> KeyIter;
|
||||
typedef TransformIter<IT,ValType> ValIter;
|
||||
|
||||
static KeyType takeFirst (PairType const& pair) { return pair.first; }
|
||||
static ValType takeSecond(PairType const& pair) { return pair.second;}
|
||||
};
|
||||
|
||||
|
||||
template<class IT>
|
||||
typename _PairIterT<IT>::KeyIter
|
||||
takePairFirst (IT const& source)
|
||||
{
|
||||
typedef typename CON::iterator::value_type Val;
|
||||
typedef typename IterSource<Val>::iterator Iter;
|
||||
};
|
||||
return transformIterator(source, _PairIterT<IT>::takeFirst );
|
||||
}
|
||||
|
||||
template<class IT>
|
||||
typename _PairIterT<IT>::KeyIter
|
||||
takePairSecond (IT const& source)
|
||||
{
|
||||
return transformIterator(source, _PairIterT<IT>::takeSecond );
|
||||
}
|
||||
|
||||
} //(END) type helpers...
|
||||
|
||||
template<class MAP>
|
||||
struct _MapType
|
||||
{
|
||||
typedef typename MAP::key_type Key;
|
||||
typedef typename IterSource<Key>::iterator Iter;
|
||||
};
|
||||
}
|
||||
|
||||
template<class MAP>
|
||||
typename iter_impl::_MapType<MAP>::Iter
|
||||
eachMapKey (MAP& map)
|
||||
|
||||
|
||||
/** wraps a given Lumiera Forward Iterator,
|
||||
* exposing just a IterSource based frontend.
|
||||
*/
|
||||
template<class IT>
|
||||
typename _IterT<IT>::Iter
|
||||
wrapIter (IT const& source)
|
||||
{
|
||||
UNIMPLEMENTED ("standard iter wrapper yielding all map keys");
|
||||
typedef typename _IterT<IT>::Val ValType;
|
||||
|
||||
return IterSource<ValType>::build (new WrappedLumieraIterator<IT> (source));
|
||||
}
|
||||
|
||||
|
||||
template<class MAP>
|
||||
typename iter_impl::_MapType<MAP>::Iter
|
||||
eachDistinctKey (MAP& map)
|
||||
|
||||
|
||||
/** @return a Lumiera Forward Iterator to yield
|
||||
* all the keys of the given Map or Hashtable
|
||||
*/
|
||||
template<class MAP>
|
||||
typename _MapT<MAP>::KeyIter
|
||||
eachMapKey (MAP& map)
|
||||
{
|
||||
typedef RangeIter<typename MAP::iterator> Range;
|
||||
|
||||
Range contents (map.begin(), map.end());
|
||||
return wrapIter (takePairFirst (contents));
|
||||
}
|
||||
|
||||
|
||||
/** @return a Lumiera Forward Iterator to yield
|
||||
* all the keys of the given Map or Hashtable
|
||||
*/
|
||||
template<class MAP>
|
||||
typename _MapT<MAP>::ValIter
|
||||
eachMapValue (MAP& map)
|
||||
{
|
||||
typedef RangeIter<typename MAP::iterator> Range;
|
||||
|
||||
Range contents (map.begin(), map.end());
|
||||
return wrapIter (takePairSecond(contents));
|
||||
}
|
||||
|
||||
|
||||
/** @return a Lumiera Forward Iterator to yield
|
||||
* all \em distinct keys of a Multimap
|
||||
*/
|
||||
template<class MAP>
|
||||
typename _MapT<MAP>::KeyIter
|
||||
eachDistinctKey (MAP&) // map)
|
||||
{
|
||||
UNIMPLEMENTED ("standard iter wrapper yielding all distinct keys of a multimap");
|
||||
}
|
||||
|
||||
|
||||
template<class CON>
|
||||
typename iter_impl::_SeqType<CON>::Iter
|
||||
eachEntry (CON& container)
|
||||
|
||||
|
||||
/** @param container a STL-like container, providing
|
||||
* - a typedef \c iterator
|
||||
* - functions \c begin() and \c end()
|
||||
* @return a Lumiera Forward Iterator yielding all values
|
||||
* starting with \c begin and excluding \c end .
|
||||
*/
|
||||
template<class CON>
|
||||
typename _SeqT<CON>::Iter
|
||||
eachEntry (CON& container)
|
||||
{
|
||||
typedef typename iter_impl::_SeqType<CON>::Val ValType;
|
||||
typedef typename _SeqT<CON>::Val ValType;
|
||||
typedef RangeIter<typename CON::iterator> Range;
|
||||
|
||||
Range contents (container.begin(), container.end());
|
||||
return IterSource<ValType>::build (new WrappedLumieraIterator<Range>(contents));
|
||||
}
|
||||
|
||||
}
|
||||
using iter_impl::wrapIter;
|
||||
using iter_impl::eachMapKey;
|
||||
using iter_impl::eachDistinctKey;
|
||||
using iter_impl::eachEntry;
|
||||
|
||||
|
||||
} // namespace lib
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
#include "lib/meta/function-closure.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <tr1/functional>
|
||||
|
||||
|
|
@ -60,6 +61,7 @@ namespace wrapper {
|
|||
using lumiera::typelist::FunctionSignature;
|
||||
using lumiera::error::LUMIERA_ERROR_BOTTOM_VALUE;
|
||||
|
||||
using boost::remove_const;
|
||||
using std::tr1::function;
|
||||
|
||||
|
||||
|
|
@ -117,6 +119,10 @@ namespace wrapper {
|
|||
class ItemWrapper
|
||||
: public BoolCheckable<ItemWrapper<TY> >
|
||||
{
|
||||
|
||||
typedef typename remove_const<TY>::type TY_unconst;
|
||||
|
||||
|
||||
mutable
|
||||
char content_[sizeof(TY)];
|
||||
bool created_;
|
||||
|
|
@ -141,6 +147,11 @@ namespace wrapper {
|
|||
return reinterpret_cast<TY&> (content_);
|
||||
}
|
||||
|
||||
TY_unconst&
|
||||
access_unconst() const ///< used to assign new buffer contents
|
||||
{
|
||||
return const_cast<TY_unconst&> (access());
|
||||
}
|
||||
|
||||
public:
|
||||
ItemWrapper()
|
||||
|
|
@ -185,7 +196,7 @@ namespace wrapper {
|
|||
if (!isSameObject (something, access() ))
|
||||
{
|
||||
if (created_)
|
||||
access() = something;
|
||||
access_unconst() = something;
|
||||
else
|
||||
build (something);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -305,13 +305,13 @@ namespace session {
|
|||
|
||||
/* == access for self-test == */
|
||||
|
||||
typedef lib::IterSource<PID>::iterator IDIter;
|
||||
typedef lib::IterSource<const PID>::iterator IDIter;
|
||||
|
||||
PlacementMO* _root_4check () { return root_.get(); }
|
||||
PlacementMO* _element_4check (ID id){ return base_entry(id).element.get();}
|
||||
PlacementMO* _scope_4check (ID id) { return base_entry(id).scope.get(); }
|
||||
IDIter _eachEntry_4check () { return eachMapKey (placementTab_); }
|
||||
IDIter _eachScope_4check() { return eachDistinctKey (scopeTab_); }
|
||||
IDIter _eachScope_4check () { return eachDistinctKey (scopeTab_); }
|
||||
|
||||
|
||||
private:
|
||||
|
|
|
|||
Loading…
Reference in a new issue