diff options
Diffstat (limited to 'libcult/cult/containers')
-rw-r--r-- | libcult/cult/containers/any.hxx | 192 | ||||
-rw-r--r-- | libcult/cult/containers/any.txx | 11 | ||||
-rw-r--r-- | libcult/cult/containers/deque.hxx | 166 | ||||
-rw-r--r-- | libcult/cult/containers/graph.hxx | 193 | ||||
-rw-r--r-- | libcult/cult/containers/graph.txx | 313 | ||||
-rw-r--r-- | libcult/cult/containers/iterator.hxx | 227 | ||||
-rw-r--r-- | libcult/cult/containers/list.hxx | 193 | ||||
-rw-r--r-- | libcult/cult/containers/map.hxx | 175 | ||||
-rw-r--r-- | libcult/cult/containers/pair.hxx | 58 | ||||
-rw-r--r-- | libcult/cult/containers/set.hxx | 175 | ||||
-rw-r--r-- | libcult/cult/containers/stack.hxx | 95 | ||||
-rw-r--r-- | libcult/cult/containers/vector.hxx | 164 |
12 files changed, 1962 insertions, 0 deletions
diff --git a/libcult/cult/containers/any.hxx b/libcult/cult/containers/any.hxx new file mode 100644 index 0000000..10f771f --- /dev/null +++ b/libcult/cult/containers/any.hxx @@ -0,0 +1,192 @@ +// file : cult/containers/any.hxx +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef CULT_CONTAINERS_ANY_HXX +#define CULT_CONTAINERS_ANY_HXX + +#include <cult/types.hxx> + +#include <cult/rtti/type-id.hxx> + +namespace Cult +{ + namespace Containers + { + //@@ eager clonning: do I need it? + // + // + class Any + { + public: + struct Typing {}; + + public: + template <typename X> + Any (X const& x) + : holder_ (new HolderTemplate<X> (x)) + { + } + + Any (Any const& any) + : holder_ (any.holder_->clone ()) + { + } + + public: + template <typename X> + Any& + operator= (X const& x) + { + holder_ = Evptr<Holder> (new HolderTemplate<X> (x)); + return *this; + } + + Any& + operator= (Any const& any) + { + holder_ = any.holder_->clone (); + return *this; + } + + public: + /* + template <typename X> + operator X& () + { + return value<X> (); + } + + template <typename X> + operator X const& () const + { + return value<X> (); + } + */ + + public: + template <typename X> + X& + value () + { + //@@ too strict + // + if (holder_->type_id () == typeid (X)) + { + return dynamic_cast<HolderTemplate<X>*>(holder_.get ())->value (); + } + else + { + throw Typing (); + } + } + + template <typename X> + X const& + value () const + { + if (holder_->type_id () == typeid (X)) + { + return dynamic_cast<HolderTemplate<X>*>(holder_.get ())->value (); + } + else + { + throw Typing (); + } + } + + public: + RTTI::TypeId + type_id () const + { + return holder_->type_id (); + } + + public: + /* + template <typename x> + friend x + operator+ (any const& a, x const& b) + { + return a.value<x> () + b; + } + + template <typename x> + friend x + operator+ (x const& a, any const& b) + { + return a + b.value<x> (); + } + */ + + private: + class Holder + { + public: + virtual + ~Holder () + { + } + + Evptr<Holder> + clone () const + { + return clone_ (); + } + + virtual RTTI::TypeId + type_id () const = 0; + + protected: + virtual Evptr<Holder> + clone_ () const = 0; + }; + + template <typename X> + class HolderTemplate : public Holder + { + public: + HolderTemplate (X const& value) + : value_ (value) + { + } + + virtual RTTI::TypeId + type_id () const + { + return RTTI::TypeId (typeid (value_)); + } + + X const& + value () const + { + return value_; + } + + X& + value () + { + return value_; + } + + protected: + virtual Evptr<Holder> + clone_ () const + { + return new HolderTemplate<X> (value_); + } + + private: + X value_; + }; + + private: + Evptr<Holder> holder_; + }; + } +} + +#include <cult/containers/any.txx> + +#endif // CULT_CONTAINERS_ANY_HXX diff --git a/libcult/cult/containers/any.txx b/libcult/cult/containers/any.txx new file mode 100644 index 0000000..8e97345 --- /dev/null +++ b/libcult/cult/containers/any.txx @@ -0,0 +1,11 @@ +// file : cult/containers/any.txx +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +namespace Cult +{ + namespace Containers + { + } +} diff --git a/libcult/cult/containers/deque.hxx b/libcult/cult/containers/deque.hxx new file mode 100644 index 0000000..ed17a0c --- /dev/null +++ b/libcult/cult/containers/deque.hxx @@ -0,0 +1,166 @@ +// file : cult/containers/deque.hxx +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef CULT_CONTAINERS_DEQUE_HXX +#define CULT_CONTAINERS_DEQUE_HXX + +#include <cult/types.hxx> + +#include <cult/containers/iterator.hxx> + +#include <deque> + +namespace Cult +{ + namespace Containers + { + template <typename T> + class Deque: public std::deque<T> + { + typedef std::deque<T> Base; + + Base& + base () + { + return *this; + } + + Base const& + base () const + { + return *this; + } + + public: + typedef typename Base::value_type Value; + + + typedef typename Base::reference Reference; + typedef typename Base::const_reference ConstReference; + + + typedef typename Base::pointer Pointer; + typedef typename Base::const_pointer ConstPointer; + + + typedef + IteratorAdapter<typename Base::iterator> + Iterator; + + typedef + IteratorAdapter<typename Base::const_iterator> + ConstIterator; + + + typedef + IteratorAdapter<typename Base::reverse_iterator> + ReverseIterator; + + typedef + IteratorAdapter<typename Base::const_reverse_iterator> + ConstReverseIterator; + + + // Use Cult::Size and Cult::PtrDifference. + // + // typedef Base::size_type; + // typedef Base::difference_type; + + public: + explicit + Deque () + : Base () + { + } + + explicit + Deque (Size size, Value const& value = Value ()) + : Base (size, value) + { + } + + template <typename InputIterator> + Deque (InputIterator first, InputIterator last) + : Base (first, last) + { + } + + Deque (Deque<Value> const& other) + : Base (other) + { + } + + Deque<Value>& + operator= (Deque<Value> const& other) + { + base () = other; + return *this; + } + + public: + Iterator + begin () + { + return Iterator (base ().begin ()); + } + + Iterator + end () + { + return Iterator (base ().end ()); + } + + + ConstIterator + begin () const + { + return ConstIterator (base ().begin ()); + } + + ConstIterator + end () const + { + return ConstIterator (base ().end ()); + } + + // + // + + ReverseIterator + rbegin () + { + return ReverseIterator (base ().rbegin ()); + } + + ReverseIterator + rend () + { + return ReverseIterator (base ().rend ()); + } + + + ConstReverseIterator + rbegin () const + { + return ConstReverseIterator (base ().rbegin ()); + } + + ConstReverseIterator + rend () const + { + return ConstReverseIterator (base ().rend ()); + } + + public: + Void + swap (Deque<Value>& other) + { + base ().swap (other); + } + }; + } +} + +#endif // CULT_CONTAINERS_DEQUE_HXX diff --git a/libcult/cult/containers/graph.hxx b/libcult/cult/containers/graph.hxx new file mode 100644 index 0000000..d61cd53 --- /dev/null +++ b/libcult/cult/containers/graph.hxx @@ -0,0 +1,193 @@ +// file : cult/containers/graph.hxx +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef CULT_CONTAINERS_GRAPH_HXX +#define CULT_CONTAINERS_GRAPH_HXX + +#include <cult/types.hxx> +#include <cult/eh/exception.hxx> +#include <cult/containers/map.hxx> + +namespace Cult +{ + namespace Containers + { + template <typename N, typename E> + class Graph + { + public: + typedef N Node; + typedef E Edge; + + struct NoEdge: virtual EH::Exception {}; + struct NoNode: virtual EH::Exception {}; + + public: + template <typename T> + T& + new_node (); + + template <typename T, typename A0> + T& + new_node (A0 const&); + + template <typename T, typename A0, typename A1> + T& + new_node (A0 const&, A1 const&); + + template <typename T, typename A0, typename A1, typename A2> + T& + new_node (A0 const&, A1 const&, A2 const&); + + template <typename T, typename A0, typename A1, typename A2, + typename A3> + T& + new_node (A0 const&, A1 const&, A2 const&, A3 const&); + + template <typename T, typename A0, typename A1, typename A2, + typename A3, typename A4> + T& + new_node (A0 const&, A1 const&, A2 const&, A3 const&, A4 const&); + + template <typename T, typename A0, typename A1, typename A2, + typename A3, typename A4, typename A5> + T& + new_node (A0 const&, A1 const&, A2 const&, A3 const&, A4 const&, + A5 const&); + + template <typename T, typename A0, typename A1, typename A2, + typename A3, typename A4, typename A5, typename A6> + T& + new_node (A0 const&, A1 const&, A2 const&, A3 const&, A4 const&, + A5 const&, A6 const&); + + template <typename T, typename A0, typename A1, typename A2, + typename A3, typename A4, typename A5, typename A6, + typename A7> + T& + new_node (A0 const&, A1 const&, A2 const&, A3 const&, A4 const&, + A5 const&, A6 const&, A7 const&); + + template <typename T, typename A0, typename A1, typename A2, + typename A3, typename A4, typename A5, typename A6, + typename A7, typename A8> + T& + new_node (A0 const&, A1 const&, A2 const&, A3 const&, A4 const&, + A5 const&, A6 const&, A7 const&, A8 const&); + + template <typename T, typename A0, typename A1, typename A2, + typename A3, typename A4, typename A5, typename A6, + typename A7, typename A8, typename A9> + T& + new_node (A0 const&, A1 const&, A2 const&, A3 const&, A4 const&, + A5 const&, A6 const&, A7 const&, A8 const&, A9 const&); + + public: + template <typename T, typename Left, typename Right> + T& + new_edge (Left&, Right&); + + template <typename T, typename Left, typename Right, + typename A0> + T& + new_edge (Left&, Right&, A0 const&); + + template <typename T, typename Left, typename Right, + typename A0, typename A1> + T& + new_edge (Left&, Right&, A0 const&, A1 const&); + + template <typename T, typename Left, typename Right, + typename A0, typename A1, typename A2> + T& + new_edge (Left&, Right&, A0 const&, A1 const&, A2 const&); + + template <typename T, typename Left, typename Right, + typename A0, typename A1, typename A2, typename A3> + T& + new_edge (Left&, Right&, A0 const&, A1 const&, A2 const&, A3 const&); + + template <typename T, typename Left, typename Right, + typename A0, typename A1, typename A2, typename A3, + typename A4> + T& + new_edge (Left&, Right&, A0 const&, A1 const&, A2 const&, A3 const&, + A4 const&); + + template <typename T, typename Left, typename Right, + typename A0, typename A1, typename A2, typename A3, + typename A4, typename A5> + T& + new_edge (Left&, Right&, A0 const&, A1 const&, A2 const&, A3 const&, + A4 const&, A5 const&); + + // Functions to reset edge's nodes. + // + public: + template <typename TE, typename TN> + Void + reset_left_node (TE& edge, TN& node) + { + edge.set_left_node (node); + } + + template <typename TE, typename TN> + Void + reset_right_node (TE& edge, TN& node) + { + edge.set_right_node (node); + } + + // Functions to add edges to a node. + // + public: + template <typename TN, typename TE> + Void + add_edge_left (TN& node, TE& edge) + { + node.add_edge_left (edge); + } + + template <typename TN, typename TE> + Void + add_edge_right (TN& node, TE& edge) + { + node.add_edge_right (edge); + } + + // Functions to delete edges and nodes. In order to delete a + // a node without leaving any dangling edges you need to make + // sure that each edge pointing to it is either deleted or reset + // to some other node. + // + public: + template <typename T, typename Left, typename Right> + Void + delete_edge (Left& left_node, Right& right_node, T& edge); + + Void + delete_node (Node& node) + { + if (nodes_.erase (&node) == 0) + throw NoNode (); + } + + protected: + typedef Shptr<Node> NodePtr; + typedef Shptr<Edge> EdgePtr; + + typedef Map<Node*, NodePtr> Nodes; + typedef Map<Edge*, EdgePtr> Edges; + + Nodes nodes_; + Edges edges_; + }; + } +} + + +#include <cult/containers/graph.txx> + +#endif // CULT_CONTAINERS_GRAPH_HXX diff --git a/libcult/cult/containers/graph.txx b/libcult/cult/containers/graph.txx new file mode 100644 index 0000000..a9c9979 --- /dev/null +++ b/libcult/cult/containers/graph.txx @@ -0,0 +1,313 @@ +// file : cult/containers/graph.txx +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +namespace Cult +{ + namespace Containers + { + + // Nodes. + // + + template <typename N, typename E> + template <typename T> + T& Graph<N, E>:: + new_node () + { + Shptr<T> node (new T); + nodes_[node.get ()] = node; + + return *node; + } + + + template <typename N, typename E> + template <typename T, typename A0> + T& Graph<N, E>:: + new_node (A0 const& a0) + { + Shptr<T> node (new T (a0)); + nodes_[node.get ()] = node; + + return *node; + } + + + template <typename N, typename E> + template <typename T, typename A0, typename A1> + T& Graph<N, E>:: + new_node (A0 const& a0, A1 const& a1) + { + Shptr<T> node (new T (a0, a1)); + nodes_[node.get ()] = node; + + return *node; + } + + template <typename N, typename E> + template <typename T, typename A0, typename A1, typename A2> + T& Graph<N, E>:: + new_node (A0 const& a0, A1 const& a1, A2 const& a2) + { + Shptr<T> node (new T (a0, a1, a2)); + nodes_[node.get ()] = node; + + return *node; + } + + template <typename N, typename E> + template <typename T, typename A0, typename A1, typename A2, + typename A3> + T& Graph<N, E>:: + new_node (A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3) + { + Shptr<T> node (new T (a0, a1, a2, a3)); + nodes_[node.get ()] = node; + + return *node; + } + + template <typename N, typename E> + template <typename T, typename A0, typename A1, typename A2, + typename A3, typename A4> + T& Graph<N, E>:: + new_node (A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, + A4 const& a4) + { + Shptr<T> node (new T (a0, a1, a2, a3, a4)); + nodes_[node.get ()] = node; + + return *node; + } + + template <typename N, typename E> + template <typename T, typename A0, typename A1, typename A2, + typename A3, typename A4, typename A5> + T& Graph<N, E>:: + new_node (A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, + A4 const& a4, A5 const& a5) + { + Shptr<T> node (new T (a0, a1, a2, a3, a4, a5)); + nodes_[node.get ()] = node; + + return *node; + } + + template <typename N, typename E> + template <typename T, typename A0, typename A1, typename A2, + typename A3, typename A4, typename A5, typename A6> + T& Graph<N, E>:: + new_node (A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, + A4 const& a4, A5 const& a5, A6 const& a6) + { + Shptr<T> node (new T (a0, a1, a2, a3, a4, a5, a6)); + nodes_[node.get ()] = node; + + return *node; + } + + template <typename N, typename E> + template <typename T, typename A0, typename A1, typename A2, + typename A3, typename A4, typename A5, typename A6, + typename A7> + T& Graph<N, E>:: + new_node (A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, + A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7) + { + Shptr<T> node (new T (a0, a1, a2, a3, a4, a5, a6, a7)); + nodes_[node.get ()] = node; + + return *node; + } + + + template <typename N, typename E> + template <typename T, typename A0, typename A1, typename A2, + typename A3, typename A4, typename A5, typename A6, + typename A7, typename A8> + T& Graph<N, E>:: + new_node (A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, + A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, + A8 const& a8) + { + Shptr<T> node (new T (a0, a1, a2, a3, a4, a5, a6, a7, a8)); + nodes_[node.get ()] = node; + + return *node; + } + + + template <typename N, typename E> + template <typename T, typename A0, typename A1, typename A2, + typename A3, typename A4, typename A5, typename A6, + typename A7, typename A8, typename A9> + T& Graph<N, E>:: + new_node (A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, + A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, + A8 const& a8, A9 const& a9) + { + Shptr<T> node (new T (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); + nodes_[node.get ()] = node; + + return *node; + } + + + // Edges. + // + + template <typename N, typename E> + template <typename T, typename Left, typename Right> + T& Graph<N, E>:: + new_edge (Left& l, Right& r) + { + Shptr<T> edge (new T); + edges_[edge.get ()] = edge; + + edge->set_left_node (l); + edge->set_right_node (r); + + l.add_edge_left (*edge); + r.add_edge_right (*edge); + + return *edge; + } + + template <typename N, typename E> + template <typename T, typename Left, typename Right, + typename A0> + T& Graph<N, E>:: + new_edge (Left& l, Right& r, A0 const& a0) + { + Shptr<T> edge (new T (a0)); + edges_[edge.get ()] = edge; + + edge->set_left_node (l); + edge->set_right_node (r); + + l.add_edge_left (*edge); + r.add_edge_right (*edge); + + return *edge; + } + + template <typename N, typename E> + template <typename T, typename Left, typename Right, + typename A0, typename A1> + T& Graph<N, E>:: + new_edge (Left& l, Right& r, A0 const& a0, A1 const& a1) + { + Shptr<T> edge (new T (a0, a1)); + edges_[edge.get ()] = edge; + + edge->set_left_node (l); + edge->set_right_node (r); + + l.add_edge_left (*edge); + r.add_edge_right (*edge); + + return *edge; + } + + template <typename N, typename E> + template <typename T, typename Left, typename Right, + typename A0, typename A1, typename A2> + T& Graph<N, E>:: + new_edge (Left& l, Right& r, A0 const& a0, A1 const& a1, A2 const& a2) + { + Shptr<T> edge (new T (a0, a1, a2)); + edges_[edge.get ()] = edge; + + edge->set_left_node (l); + edge->set_right_node (r); + + l.add_edge_left (*edge); + r.add_edge_right (*edge); + + return *edge; + } + + template <typename N, typename E> + template <typename T, typename Left, typename Right, + typename A0, typename A1, typename A2, typename A3> + T& Graph<N, E>:: + new_edge (Left& l, Right& r, A0 const& a0, A1 const& a1, A2 const& a2, + A3 const& a3) + { + Shptr<T> edge (new T (a0, a1, a2, a3)); + edges_[edge.get ()] = edge; + + edge->set_left_node (l); + edge->set_right_node (r); + + l.add_edge_left (*edge); + r.add_edge_right (*edge); + + return *edge; + } + + template <typename N, typename E> + template <typename T, typename Left, typename Right, + typename A0, typename A1, typename A2, typename A3, + typename A4> + T& Graph<N, E>:: + new_edge (Left& l, Right& r, A0 const& a0, A1 const& a1, A2 const& a2, + A3 const& a3, A4 const& a4) + { + Shptr<T> edge (new T (a0, a1, a2, a3, a4)); + edges_[edge.get ()] = edge; + + edge->set_left_node (l); + edge->set_right_node (r); + + l.add_edge_left (*edge); + r.add_edge_right (*edge); + + return *edge; + } + + template <typename N, typename E> + template <typename T, typename Left, typename Right, + typename A0, typename A1, typename A2, typename A3, + typename A4, typename A5> + T& Graph<N, E>:: + new_edge (Left& l, Right& r, A0 const& a0, A1 const& a1, A2 const& a2, + A3 const& a3, A4 const& a4, A5 const& a5) + { + Shptr<T> edge (new T (a0, a1, a2, a3, a4, a5)); + edges_[edge.get ()] = edge; + + edge->set_left_node (l); + edge->set_right_node (r); + + l.add_edge_left (*edge); + r.add_edge_right (*edge); + + return *edge; + } + + + template <typename N, typename E> + template <typename T, typename Left, typename Right> + Void Graph<N, E>:: + delete_edge (Left& l, Right& r, T& edge) + { + typename Edges::Iterator i (edges_.find (&edge)); + + if (i == edges_.end () || + nodes_.find (&l) == nodes_.end () || + nodes_.find (&r) == nodes_.end ()) + throw NoEdge (); + + r.remove_edge_right (edge); + l.remove_edge_left (edge); + + edge.clear_right_node (r); + edge.clear_left_node (l); + + edges_.erase (i); + } + } +} diff --git a/libcult/cult/containers/iterator.hxx b/libcult/cult/containers/iterator.hxx new file mode 100644 index 0000000..132043b --- /dev/null +++ b/libcult/cult/containers/iterator.hxx @@ -0,0 +1,227 @@ +// file : cult/containers/iterator.hxx +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef CULT_CONTAINERS_ITERATOR_HXX +#define CULT_CONTAINERS_ITERATOR_HXX + +#include <cult/types.hxx> + +#include <iterator> + +namespace Cult +{ + namespace Containers + { + template <typename I> + class IteratorAdapter + { + public: + typedef typename std::iterator_traits<I>::value_type Value; + typedef typename std::iterator_traits<I>::difference_type Difference; + typedef typename std::iterator_traits<I>::pointer Pointer; + typedef typename std::iterator_traits<I>::reference Reference; + typedef typename std::iterator_traits<I>::iterator_category Category; + + // For compatibility with std::iterator_traits + // + public: + typedef Value value_type; + typedef Reference reference; + typedef Pointer pointer; + typedef Category iterator_category; + typedef Difference difference_type; + + public: + IteratorAdapter () + : i_ () // i_ can be of a pointer type. + { + } + + explicit + IteratorAdapter (I const& i) + : i_ (i) + { + } + + template <typename J> + IteratorAdapter (IteratorAdapter<J> const& j) + : i_ (j.i_) + { + } + public: + // Forward iterator requirements. + // + Reference + operator* () const + { + return *i_; + } + + Pointer + operator-> () const + { + return &(*i_); + } + + IteratorAdapter& + operator++ () + { + ++i_; + return *this; + } + + IteratorAdapter + operator++ (Int) + { + return IteratorAdapter (i_++); + } + + public: + // Bidirectional iterator requirements. + // + IteratorAdapter& + operator-- () + { + --i_; + return *this; + } + + IteratorAdapter + operator-- (Int) + { + return IteratorAdapter (i_--); + } + + public: + // Random access iterator requirements. + // + Reference + operator[] (Difference n) const + { + return i_[n]; + } + + IteratorAdapter + operator+ (Difference n) const + { + return IteratorAdapter (i_ + n); + } + + IteratorAdapter& + operator+= (Difference n) + { + i_ += n; + return *this; + } + + IteratorAdapter + operator- (Difference n) const + { + return IteratorAdapter (i_ - n); + } + + IteratorAdapter& + operator-= (Difference n) + { + i_ += n; + return *this; + } + + public: + I const& + base () const + { + return i_; + } + + // @@ This is needed so that call to functions such as erase() + // be possible without writing a wrapper. This should be a temporary + // measure. + + operator I& () + { + return i_; + } + + operator I const& () const + { + return i_; + } + + private: + template<typename> + friend class IteratorAdapter; + + I i_; + }; + + // Note: We use different types for left- and right-hand-side + // arguments to allow comparison between iterator and const_iterator. + // + + // Forward iterator requirements. + // + template <typename I, typename J> + inline Boolean + operator== (IteratorAdapter<I> const& i, IteratorAdapter<J> const& j) + { + return i.base () == j.base (); + } + + template <typename I, typename J> + inline Boolean + operator!= (IteratorAdapter<I> const& i, IteratorAdapter<J> const& j) + { + return i.base () != j.base (); + } + + // Random access iterator requirements + // + template <typename I, typename J> + inline Boolean + operator< (IteratorAdapter<I> const& i, IteratorAdapter<J> const& j) + { + return i.base() < j.base(); + } + + template <typename I, typename J> + inline Boolean + operator> (IteratorAdapter<I> const& i, IteratorAdapter<J> const& j) + { + return i.base() > j.base(); + } + + template <typename I, typename J> + inline Boolean + operator<= (IteratorAdapter<I> const& i, IteratorAdapter<J> const& j) + { + return i.base() <= j.base(); + } + + template <typename I, typename J> + inline Boolean + operator>= (IteratorAdapter<I> const& i, IteratorAdapter<J> const& j) + { + return i.base() >= j.base(); + } + + template <typename I, typename J> + inline typename IteratorAdapter<I>::Difference + operator- (IteratorAdapter<I> const& i, IteratorAdapter<J> const& j) + { + return i.base () - j.base (); + } + + template <typename I> + IteratorAdapter<I> + operator+ (typename IteratorAdapter<I>::Difference n, + IteratorAdapter<I> const& x) + { + return x + n; + } + } +} + +#endif // CULT_CONTAINERS_ITERATOR_HXX diff --git a/libcult/cult/containers/list.hxx b/libcult/cult/containers/list.hxx new file mode 100644 index 0000000..161052e --- /dev/null +++ b/libcult/cult/containers/list.hxx @@ -0,0 +1,193 @@ +// file : cult/containers/list.hxx +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef CULT_CONTAINERS_LIST_HXX +#define CULT_CONTAINERS_LIST_HXX + +#include <cult/types.hxx> + +#include <cult/containers/iterator.hxx> + +#include <list> + +namespace Cult +{ + namespace Containers + { + template <typename T> + class List: public std::list<T> + { + typedef std::list<T> Base; + + Base& + base () + { + return *this; + } + + Base const& + base () const + { + return *this; + } + + public: + typedef typename Base::value_type Value; + + typedef typename Base::reference Reference; + typedef typename Base::const_reference ConstReference; + + typedef typename Base::pointer Pointer; + typedef typename Base::const_pointer ConstPointer; + + + typedef + IteratorAdapter<typename Base::iterator> + Iterator; + + typedef + IteratorAdapter<typename Base::const_iterator> + ConstIterator; + + + typedef + IteratorAdapter<typename Base::reverse_iterator> + ReverseIterator; + + typedef + IteratorAdapter<typename Base::const_reverse_iterator> + ConstReverseIterator; + + + // Use Cult::Size and Cult::PtrDifference. + // + // typedef Base::size_type; + // typedef Base::difference_type; + + public: + explicit + List () + : Base () + { + } + + explicit + List (Size size, Value const& value = Value ()) + : Base (size, value) + { + } + + template <typename InputIterator> + List (InputIterator first, InputIterator last) + : Base (first, last) + { + } + + List (List<Value> const& other) + : Base (other) + { + } + + List<Value>& + operator= (List<Value> const& other) + { + base () = other; + return *this; + } + + public: + Void + swap (List<Value>& other) + { + base ().swap (other); + } + + public: + Iterator + begin () + { + return Iterator (base ().begin ()); + } + + Iterator + end () + { + return Iterator (base ().end ()); + } + + + ConstIterator + begin () const + { + return ConstIterator (base ().begin ()); + } + + ConstIterator + end () const + { + return ConstIterator (base ().end ()); + } + + // + // + + ReverseIterator + rbegin () + { + return ReverseIterator (base ().rbegin ()); + } + + ReverseIterator + rend () + { + return ReverseIterator (base ().rend ()); + } + + + ConstReverseIterator + rbegin () const + { + return ConstReverseIterator (base ().rbegin ()); + } + + ConstReverseIterator + rend () const + { + return ConstReverseIterator (base ().rend ()); + } + + public: + Iterator + insert (Iterator const& p, Value const& x) + { + return Iterator (base ().insert (p.base (), x)); + } + + template <typename I> + Void + insert (Iterator const& p, I const& first, I const& last) + { + base ().insert (p.base (), first, last); + } + + template <typename I> + Void + insert (Iterator const& p, + IteratorAdapter<I> const& first, + IteratorAdapter<I> const& last) + { + base ().insert (p.base (), first.base (), last.base ()); + } + + Iterator + erase (Iterator const& i) + { + return Iterator (base ().erase (i.base ())); + } + }; + } +} + +#endif // CULT_CONTAINERS_LIST_HXX diff --git a/libcult/cult/containers/map.hxx b/libcult/cult/containers/map.hxx new file mode 100644 index 0000000..8a3fbdb --- /dev/null +++ b/libcult/cult/containers/map.hxx @@ -0,0 +1,175 @@ +// file : cult/containers/map.hxx +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef CULT_CONTAINERS_MAP_HXX +#define CULT_CONTAINERS_MAP_HXX + +#include <cult/types.hxx> + +#include <cult/containers/iterator.hxx> + +#include <map> + +namespace Cult +{ + namespace Containers + { + template <typename K, typename T, typename C = std::less<K> > + class Map: public std::map<K, T, C> + { + typedef std::map<K, T, C> Base; + + Base& + base () + { + return *this; + } + + Base const& + base () const + { + return *this; + } + + public: + typedef typename Base::key_type Key; + typedef typename Base::mapped_type Value; + typedef typename Base::value_type Pair; + typedef typename Base::key_compare Compare; + + typedef typename Base::reference Reference; + typedef typename Base::const_reference ConstReference; + + typedef typename Base::pointer Pointer; + typedef typename Base::const_pointer ConstPointer; + + + typedef + IteratorAdapter<typename Base::iterator> + Iterator; + + typedef + IteratorAdapter<typename Base::const_iterator> + ConstIterator; + + + typedef + IteratorAdapter<typename Base::reverse_iterator> + ReverseIterator; + + typedef + IteratorAdapter<typename Base::const_reverse_iterator> + ConstReverseIterator; + + // Use Cult::Size and Cult::PtrDifference. + // + // typedef Base::size_type; + // typedef Base::difference_type; + + public: + explicit + Map (Compare const& comp = Compare ()) + : Base (comp) + { + } + + template <typename InputIterator> + Map (InputIterator first, + InputIterator last, + Compare const& comp = Compare ()) + : Base (first, last, comp) + { + } + + Map (Map<Key, Value, Compare> const& other) + : Base (other) + { + } + + Map<Key, Value, Compare>& + operator= (Map<Key, Value, Compare> const& other) + { + base () = other; + return *this; + } + + public: + Iterator + begin () + { + return Iterator (base ().begin ()); + } + + Iterator + end () + { + return Iterator (base ().end ()); + } + + + ConstIterator + begin () const + { + return ConstIterator (base ().begin ()); + } + + ConstIterator + end () const + { + return ConstIterator (base ().end ()); + } + + // + // + + ReverseIterator + rbegin () + { + return ReverseIterator (base ().rbegin ()); + } + + ReverseIterator + rend () + { + return ReverseIterator (base ().rend ()); + } + + + ConstReverseIterator + rbegin () const + { + return ConstReverseIterator (base ().rbegin ()); + } + + ConstReverseIterator + rend () const + { + return ConstReverseIterator (base ().rend ()); + } + + public: + Iterator + find (Key const& k) + { + return Iterator (base ().find (k)); + } + + ConstIterator + find (Key const& k) const + { + return ConstIterator (base ().find (k)); + } + + public: + Void + swap (Map<Key, Value, Compare>& other) + { + base ().swap (other); + } + }; + } +} + +#endif // CULT_CONTAINERS_MAP_HXX diff --git a/libcult/cult/containers/pair.hxx b/libcult/cult/containers/pair.hxx new file mode 100644 index 0000000..b8b7506 --- /dev/null +++ b/libcult/cult/containers/pair.hxx @@ -0,0 +1,58 @@ +// file : cult/containers/pair.hxx +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef CULT_CONTAINERS_PAIR_HXX +#define CULT_CONTAINERS_PAIR_HXX + +#include <utility> + +namespace Cult +{ + namespace Containers + { + template <typename T1, typename T2> + class Pair: public std::pair<T1, T2> + { + typedef std::pair<T1, T2> Base; + + Base& + base () + { + return *this; + } + + public: + typedef T1 First; + typedef T2 Second; + + public: + Pair () + : Base () + { + } + + Pair (First const& first, Second const& second) + : Base (first, second) + { + } + + template <typename X, typename Y> + Pair (std::pair<X, Y> const& pair) + : Base (pair) + { + } + + template <typename X, typename Y> + Pair& + operator= (std::pair<X, Y> const& pair) + { + base () = pair; + return *this; + } + }; + } +} + +#endif // CULT_CONTAINERS_PAIR_HXX diff --git a/libcult/cult/containers/set.hxx b/libcult/cult/containers/set.hxx new file mode 100644 index 0000000..a911c19 --- /dev/null +++ b/libcult/cult/containers/set.hxx @@ -0,0 +1,175 @@ +// file : cult/containers/set.hxx +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef CULT_CONTAINERS_SET_HXX +#define CULT_CONTAINERS_SET_HXX + +#include <cult/types.hxx> + +#include <cult/containers/iterator.hxx> + +#include <set> + +namespace Cult +{ + namespace Containers + { + template <typename K, typename C = std::less<K> > + class Set: public std::set<K, C> + { + typedef std::set<K, C> Base; + + Base& + base () + { + return *this; + } + + Base const& + base () const + { + return *this; + } + + public: + typedef typename Base::key_type Key; + typedef typename Base::value_type Value; // Same as Key. + typedef typename Base::key_compare Compare; + + typedef typename Base::reference Reference; + typedef typename Base::const_reference ConstReference; + + typedef typename Base::pointer Pointer; + typedef typename Base::const_pointer ConstPointer; + + + typedef + IteratorAdapter<typename Base::iterator> + Iterator; + + typedef + IteratorAdapter<typename Base::const_iterator> + ConstIterator; + + + typedef + IteratorAdapter<typename Base::reverse_iterator> + ReverseIterator; + + typedef + IteratorAdapter<typename Base::const_reverse_iterator> + ConstReverseIterator; + + + // Use Cult::Size and Cult::PtrDifference. + // + // typedef Base::size_type; + // typedef Base::difference_type; + + public: + explicit + Set (Compare const& comp = Compare ()) + : Base (comp) + { + } + + template <typename InputIterator> + Set (InputIterator first, + InputIterator last, + Compare const& comp = Compare ()) + : Base (first, last, comp) + { + } + + Set (Set<Key, Compare> const& other) + : Base (other) + { + } + + Set<Key, Compare>& + operator= (Set<Key, Compare> const& other) + { + base () = other; + return *this; + } + + public: + Iterator + begin () + { + return Iterator (base ().begin ()); + } + + Iterator + end () + { + return Iterator (base ().end ()); + } + + + ConstIterator + begin () const + { + return ConstIterator (base ().begin ()); + } + + ConstIterator + end () const + { + return ConstIterator (base ().end ()); + } + + // + // + + ReverseIterator + rbegin () + { + return ReverseIterator (base ().rbegin ()); + } + + ReverseIterator + rend () + { + return ReverseIterator (base ().rend ()); + } + + + ConstReverseIterator + rbegin () const + { + return ConstReverseIterator (base ().rbegin ()); + } + + ConstReverseIterator + rend () const + { + return ConstReverseIterator (base ().rend ()); + } + + public: + Iterator + find (Key const& k) + { + return Iterator (base ().find (k)); + } + + ConstIterator + find (Key const& k) const + { + return ConstIterator (base ().find (k)); + } + + public: + Void + swap (Set<Key, Compare>& other) + { + base ().swap (other); + } + }; + } +} + +#endif // CULT_CONTAINERS_SET_HXX diff --git a/libcult/cult/containers/stack.hxx b/libcult/cult/containers/stack.hxx new file mode 100644 index 0000000..930bfe8 --- /dev/null +++ b/libcult/cult/containers/stack.hxx @@ -0,0 +1,95 @@ +// file : cult/containers/stack.hxx +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef CULT_CONTAINERS_STACK_HXX +#define CULT_CONTAINERS_STACK_HXX + +#include <cult/types.hxx> + +#include <cult/containers/deque.hxx> + +namespace Cult +{ + namespace Containers + { + template <typename T, typename C = Deque<T> > + class Stack + { + public: + typedef C Container; + typedef typename Container::Value Value; + + + public: + explicit + Stack (Container const& c = Container()) + : c_ (c) + { + } + + Boolean + empty () const + { + return c_.empty(); + } + + Size + size () const + { + return c_.size(); + } + + Value& + top () + { + return c_.back(); + } + + Value const& + top () const + { + return c_.back(); + } + + Void + push (const Value& x) + { + c_.push_back(x); + } + + Void + pop() + { + c_.pop_back(); + } + + protected: + Container c_; + }; + + /* + template <class T, class Container> + bool operator==(const stack<T, Container>& x, + const stack<T, Container>& y); + template <class T, class Container> + bool operator< (const stack<T, Container>& x, + const stack<T, Container>& y); + template <class T, class Container> + bool operator!=(const stack<T, Container>& x, + const stack<T, Container>& y); + template <class T, class Container> + bool operator> (const stack<T, Container>& x, + const stack<T, Container>& y); + template <class T, class Container> + bool operator>=(const stack<T, Container>& x, + const stack<T, Container>& y); + template <class T, class Container> + bool operator<=(const stack<T, Container>& x, + const stack<T, Container>& y); + */ + } +} + +#endif // CULT_CONTAINERS_STACK_HXX diff --git a/libcult/cult/containers/vector.hxx b/libcult/cult/containers/vector.hxx new file mode 100644 index 0000000..3a3b32f --- /dev/null +++ b/libcult/cult/containers/vector.hxx @@ -0,0 +1,164 @@ +// file : cult/containers/vector.hxx +// author : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef CULT_CONTAINERS_VECTOR_HXX +#define CULT_CONTAINERS_VECTOR_HXX + +#include <cult/types.hxx> + +#include <cult/containers/iterator.hxx> + +#include <vector> + +namespace Cult +{ + namespace Containers + { + template <typename T> + class Vector: public std::vector<T> + { + typedef std::vector<T> Base; + + Base& + base () + { + return *this; + } + + Base const& + base () const + { + return *this; + } + + public: + typedef typename Base::value_type Value; + + typedef typename Base::reference Reference; + typedef typename Base::const_reference ConstReference; + + typedef typename Base::pointer Pointer; + typedef typename Base::const_pointer ConstPointer; + + + typedef + IteratorAdapter<typename Base::iterator> + Iterator; + + typedef + IteratorAdapter<typename Base::const_iterator> + ConstIterator; + + + typedef + IteratorAdapter<typename Base::reverse_iterator> + ReverseIterator; + + typedef + IteratorAdapter<typename Base::const_reverse_iterator> + ConstReverseIterator; + + + // Use Cult::Size and Cult::PtrDifference. + // + // typedef Base::size_type; + // typedef Base::difference_type; + + public: + explicit + Vector () + : Base () + { + } + + explicit + Vector (Size size, Value const& value = Value ()) + : Base (size, value) + { + } + + template <typename InputIterator> + Vector (InputIterator first, InputIterator last) + : Base (first, last) + { + } + + Vector (Vector<Value> const& other) + : Base (other) + { + } + + Vector<Value>& + operator= (Vector<Value> const& other) + { + base () = other; + return *this; + } + + public: + Iterator + begin () + { + return Iterator (base ().begin ()); + } + + Iterator + end () + { + return Iterator (base ().end ()); + } + + + ConstIterator + begin () const + { + return ConstIterator (base ().begin ()); + } + + ConstIterator + end () const + { + return ConstIterator (base ().end ()); + } + + // + // + + ReverseIterator + rbegin () + { + return ReverseIterator (base ().rbegin ()); + } + + ReverseIterator + rend () + { + return ReverseIterator (base ().rend ()); + } + + + ConstReverseIterator + rbegin () const + { + return ConstReverseIterator (base ().rbegin ()); + } + + ConstReverseIterator + rend () const + { + return ConstReverseIterator (base ().rend ()); + } + + public: + Void + swap (Vector<Value>& other) + { + base ().swap (other); + } + }; + } +} + +#endif // CULT_CONTAINERS_VECTOR_HXX |