diff --git a/src/lib/iter-source.hpp b/src/lib/iter-source.hpp index 13eb580e3..d822f4773 100644 --- a/src/lib/iter-source.hpp +++ b/src/lib/iter-source.hpp @@ -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 #include @@ -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 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 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 - struct _SeqType + template + struct _SeqT + { + typedef typename CON::iterator::value_type Val; + typedef typename IterSource::iterator Iter; + }; + + template + struct _MapT + { + typedef typename MAP::key_type Key; + typedef typename MAP::value_type::second_type Val; + typedef typename IterSource::iterator KeyIter; + typedef typename IterSource< Val>::iterator ValIter; + }; + + + template + struct _IterT + { + typedef typename IT::value_type Val; + typedef typename IterSource::iterator Iter; + }; + + template + struct _PairIterT + { + typedef typename IT::value_type PairType; + typedef typename PairType::first_type KeyType; + typedef typename PairType::second_type ValType; + + typedef TransformIter KeyIter; + typedef TransformIter ValIter; + + static KeyType takeFirst (PairType const& pair) { return pair.first; } + static ValType takeSecond(PairType const& pair) { return pair.second;} + }; + + + template + typename _PairIterT::KeyIter + takePairFirst (IT const& source) { - typedef typename CON::iterator::value_type Val; - typedef typename IterSource::iterator Iter; - }; + return transformIterator(source, _PairIterT::takeFirst ); + } + + template + typename _PairIterT::KeyIter + takePairSecond (IT const& source) + { + return transformIterator(source, _PairIterT::takeSecond ); + } + + } //(END) type helpers... - template - struct _MapType - { - typedef typename MAP::key_type Key; - typedef typename IterSource::iterator Iter; - }; - } - - template - typename iter_impl::_MapType::Iter - eachMapKey (MAP& map) + + + /** wraps a given Lumiera Forward Iterator, + * exposing just a IterSource based frontend. + */ + template + typename _IterT::Iter + wrapIter (IT const& source) { - UNIMPLEMENTED ("standard iter wrapper yielding all map keys"); + typedef typename _IterT::Val ValType; + + return IterSource::build (new WrappedLumieraIterator (source)); } - - - template - typename iter_impl::_MapType::Iter - eachDistinctKey (MAP& map) + + + /** @return a Lumiera Forward Iterator to yield + * all the keys of the given Map or Hashtable + */ + template + typename _MapT::KeyIter + eachMapKey (MAP& map) + { + typedef RangeIter 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 + typename _MapT::ValIter + eachMapValue (MAP& map) + { + typedef RangeIter 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 + typename _MapT::KeyIter + eachDistinctKey (MAP&) // map) { UNIMPLEMENTED ("standard iter wrapper yielding all distinct keys of a multimap"); } - - - template - typename iter_impl::_SeqType::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 + typename _SeqT::Iter + eachEntry (CON& container) { - typedef typename iter_impl::_SeqType::Val ValType; + typedef typename _SeqT::Val ValType; typedef RangeIter Range; Range contents (container.begin(), container.end()); return IterSource::build (new WrappedLumieraIterator(contents)); } + + } + using iter_impl::wrapIter; + using iter_impl::eachMapKey; + using iter_impl::eachDistinctKey; + using iter_impl::eachEntry; } // namespace lib diff --git a/src/lib/wrapper.hpp b/src/lib/wrapper.hpp index b5a240593..8b36f9b1e 100644 --- a/src/lib/wrapper.hpp +++ b/src/lib/wrapper.hpp @@ -48,6 +48,7 @@ #include "lib/meta/function-closure.hpp" #include "lib/util.hpp" +#include #include #include @@ -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 > { + + typedef typename remove_const::type TY_unconst; + + mutable char content_[sizeof(TY)]; bool created_; @@ -141,6 +147,11 @@ namespace wrapper { return reinterpret_cast (content_); } + TY_unconst& + access_unconst() const ///< used to assign new buffer contents + { + return const_cast (access()); + } public: ItemWrapper() @@ -185,7 +196,7 @@ namespace wrapper { if (!isSameObject (something, access() )) { if (created_) - access() = something; + access_unconst() = something; else build (something); } diff --git a/src/proc/mobject/session/placement-index.cpp b/src/proc/mobject/session/placement-index.cpp index 701da196b..395e5059e 100644 --- a/src/proc/mobject/session/placement-index.cpp +++ b/src/proc/mobject/session/placement-index.cpp @@ -305,13 +305,13 @@ namespace session { /* == access for self-test == */ - typedef lib::IterSource::iterator IDIter; + typedef lib::IterSource::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: