Inferno  0.2
specialise_oostd.hpp
Go to the documentation of this file.
00001 #ifndef SPECIALISE_OOSTD_HPP
00002 #define SPECIALISE_OOSTD_HPP
00003 
00004 #include "common/common.hpp"
00005 #include "common/shared_ptr.hpp"
00006 #include "common/containers.hpp"
00007 #include "itemise.hpp"
00008 #include <deque>
00009 #include <set>
00010 #include <iterator>
00011 
00012 // Inferno tree shared pointers
00013 
00014 struct Node;
00015 
00016 // TODO optimise SharedPtr, it seems to be somewhat slower than shared_ptr!!!
00017 typedef OOStd::SharedPtrInterface<Itemiser::Element, Node> TreePtrInterface;
00018 
00019 template<typename VALUE_TYPE>
00020 class TreePtr : public OOStd::SharedPtr<Itemiser::Element, Node, VALUE_TYPE>
00021 {
00022 public:
00023   inline TreePtr() : OOStd::SharedPtr<Itemiser::Element, Node, VALUE_TYPE>() {}
00024   inline TreePtr( VALUE_TYPE *o ) : OOStd::SharedPtr<Itemiser::Element, Node, VALUE_TYPE>(o) {}
00025   inline TreePtr( const TreePtrInterface &g ) : OOStd::SharedPtr<Itemiser::Element, Node, VALUE_TYPE>(g) {}
00026     inline operator TreePtr<Node>() const { return OOStd::SharedPtr<Itemiser::Element, Node, VALUE_TYPE>::operator OOStd::SharedPtr<Itemiser::Element, Node, Node>(); }
00027   inline TreePtr( const OOStd::SharedPtr<Itemiser::Element, Node, VALUE_TYPE> &g ) : OOStd::SharedPtr<Itemiser::Element, Node, VALUE_TYPE>(g) {}
00028   template< typename OTHER >
00029   inline TreePtr( const shared_ptr<OTHER> &o ) : OOStd::SharedPtr<Itemiser::Element, Node, VALUE_TYPE>(o) {}
00030   template< typename OTHER >
00031   inline TreePtr( const TreePtr<OTHER> &o ) : OOStd::SharedPtr<Itemiser::Element, Node, VALUE_TYPE>(o) {}
00032   static inline TreePtr<VALUE_TYPE> DynamicCast( const TreePtrInterface &g )
00033   {
00034     return OOStd::SharedPtr<Itemiser::Element, Node, VALUE_TYPE>::DynamicCast(g);
00035   }
00036   virtual OOStd::SharedPtr<Itemiser::Element, Node, Node> MakeValueArchitype() const
00037     {
00038         return new VALUE_TYPE; // means VALUE_TYPE must be constructable
00039     }
00040 };
00041 
00042 
00043 
00044 // Inferno tree containers
00045 typedef OOStd::ContainerInterface<Itemiser::Element, TreePtrInterface> ContainerInterface;
00046 typedef OOStd::PointIterator<Itemiser::Element, TreePtrInterface> PointIterator;
00047 typedef OOStd::CountingIterator<Itemiser::Element, TreePtrInterface> CountingIterator;
00048 typedef OOStd::SequenceInterface<Itemiser::Element, TreePtrInterface> SequenceInterface;
00049 typedef OOStd::SimpleAssociativeContainerInterface<Itemiser::Element, TreePtrInterface> CollectionInterface;
00050 
00051 template<typename VALUE_TYPE>
00052 struct Sequence : virtual OOStd::Sequence< Itemiser::Element, TreePtrInterface, deque< TreePtr<VALUE_TYPE> > >
00053 {
00054   typedef deque< TreePtr<VALUE_TYPE> > Impl;
00055 
00056   inline Sequence() {}
00057   template<typename L, typename R>
00058   inline Sequence( const pair<L, R> &p ) :
00059     OOStd::Sequence< Itemiser::Element, TreePtrInterface, Impl >( p ) {}
00060   template< typename OTHER >
00061   inline Sequence( const TreePtr<OTHER> &v ) :
00062     OOStd::Sequence< Itemiser::Element, TreePtrInterface, Impl >( v ) {}
00063 };
00064 
00065 
00066 template<typename VALUE_TYPE> 
00067 struct Collection : virtual OOStd::SimpleAssociativeContainer< Itemiser::Element, TreePtrInterface, multiset< TreePtr<VALUE_TYPE> > >
00068 {
00069   typedef multiset< TreePtr<VALUE_TYPE> > Impl;
00070 
00071   inline Collection<VALUE_TYPE>() {}
00072   template<typename L, typename R>
00073   inline Collection( const pair<L, R> &p ) :
00074     OOStd::SimpleAssociativeContainer< Itemiser::Element, TreePtrInterface, Impl >( p ) {}
00075   template< typename OTHER >
00076   inline Collection( const TreePtr<OTHER> &v ) :
00077     OOStd::SimpleAssociativeContainer< Itemiser::Element, TreePtrInterface, Impl >( v ) {}
00078 };
00079 
00080 
00081 /** Produce a container around an iterator that has already been defined.
00082     Iterator's constructor should produce an "end" iterator if constructed
00083     without parameters, otherwise a "begin" iterator. The begin constructors
00084     parameters should be supplied to the template, and will become the
00085     container's constructor parameters. Iterators don't have to be 
00086     const, but I think the container does, so clear() etc are disallowed. */
00087 template< typename Iterator, typename ConsParam1, 
00088                              typename ConsParam2=int, 
00089                              typename ConsParam3=int >
00090 class ContainerFromIterator : public ContainerInterface
00091 {
00092 public:
00093   typedef Iterator iterator; /// So that the standard Container::iterator requirement is met
00094   ContainerFromIterator( ConsParam1 p1 ) : my_begin( p1 ), my_end() {} /// Constructor for 1 param
00095     ContainerFromIterator( ConsParam1 p1, 
00096                            ConsParam2 p2 ) : my_begin( p1, p2 ), my_end() {} /// Constructor for 2 params
00097     ContainerFromIterator( ConsParam1 p1, 
00098                            ConsParam2 p2,
00099                            ConsParam2 p3 ) : my_begin( p1, p2, p3 ), my_end() {} /// Constructor for 3 params
00100     // ... add more as required
00101     
00102   virtual const iterator &begin() { return my_begin; }
00103     virtual const iterator &end()   { return my_end; }
00104     virtual void erase( ContainerInterface::iterator ) { ASSERTFAIL("Cannot modify ContainerFromIterator<>"); }
00105     virtual void clear()                               { ASSERTFAIL("Cannot modify ContainerFromIterator<>"); }    
00106     virtual void insert( const TreePtrInterface & )    { ASSERTFAIL("Cannot modify ContainerFromIterator<>"); }
00107 private:
00108     iterator my_begin, my_end;
00109 };
00110 
00111 
00112 // Handy typing saver for creating objects and SharedPtrs to them.
00113 // MakeTreePtr<X> may be constructed in the same way as X, but will then
00114 // masquerade as a SharedPtr<X> where the pointed-to X has been allocated
00115 // using new. Similar to Boost's make_shared<>() except that being an object
00116 // with a constructor, rather than a free function, it may be used in a
00117 // declaration as well as in a function-like way. So both of the following
00118 // are OK:
00119 // existing_shared_ptr = MakeTreePtr<X>(10); // as per Boost: construction of temporary looks like function call
00120 // MakeTreePtr<X> new_shared_ptr(10); // new Inferno form: new_shared_ptr may now be used like a SharedPtr<X>
00121 template<typename VALUE_TYPE>
00122 struct MakeTreePtr : TreePtr<VALUE_TYPE>
00123 {
00124   MakeTreePtr() : TreePtr<VALUE_TYPE>( new VALUE_TYPE ) {}
00125   template<typename CP0>
00126   MakeTreePtr(const CP0 &cp0) : TreePtr<VALUE_TYPE>( new VALUE_TYPE(cp0) ) {}
00127   template<typename CP0, typename CP1>
00128   MakeTreePtr(const CP0 &cp0, const CP1 &cp1) : TreePtr<VALUE_TYPE>( new VALUE_TYPE(cp0, cp1) ) {}
00129   template<typename CP0, typename CP1, typename CP2>
00130   MakeTreePtr(const CP0 &cp0, const CP1 &cp1, const CP2 &cp2) : TreePtr<VALUE_TYPE>( new VALUE_TYPE(cp0, cp1, cp2) ) {}
00131   // Add more params as needed...
00132 };
00133 
00134 
00135 #endif
00136