implement IterSource adapter for STL map and hashmap

This commit is contained in:
Fischlurch 2010-01-06 03:38:02 +01:00
parent 030a7d3813
commit 2a5b080dd7
3 changed files with 172 additions and 58 deletions

View file

@ -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

View file

@ -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);
}

View file

@ -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: