diff options
Diffstat (limited to 'cutl/container')
-rw-r--r-- | cutl/container/any.hxx | 133 | ||||
-rw-r--r-- | cutl/container/graph.hxx | 157 | ||||
-rw-r--r-- | cutl/container/graph.txx | 315 | ||||
-rw-r--r-- | cutl/container/pointer-iterator.hxx | 127 |
4 files changed, 732 insertions, 0 deletions
diff --git a/cutl/container/any.hxx b/cutl/container/any.hxx new file mode 100644 index 0000000..0c89a38 --- /dev/null +++ b/cutl/container/any.hxx @@ -0,0 +1,133 @@ +// file : cutl/container/any.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2009 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +#ifndef CUTL_CONTAINER_ANY_HXX +#define CUTL_CONTAINER_ANY_HXX + +#include <memory> // std::auto_ptr +#include <typeinfo> // std::type_info + +namespace cutl +{ + namespace container + { + class any + { + public: + struct typing {}; + + public: + template <typename X> + any (X const& x) + : holder_ (new holder_impl<X> (x)) + { + } + + any (any const& x) + : holder_ (x.holder_->clone ()) + { + } + + template <typename X> + any& + operator= (X const& x) + { + holder_.reset (new holder_impl<X> (x)); + return *this; + } + + any& + operator= (any const& x) + { + holder_.reset (x.holder_->clone ()); + return *this; + } + + public: + template <typename X> + X& + value () + { + if (holder_impl<X>* p = dynamic_cast<holder_impl<X>*> (holder_.get ())) + return p->value (); + else + throw typing (); + } + + template <typename X> + X const& + value () const + { + if (holder_impl<X>* p = dynamic_cast<holder_impl<X>*> (holder_.get ())) + return p->value (); + else + throw typing (); + } + + public: + std::type_info const& + type_info () const + { + return holder_->type_info (); + } + + private: + class holder + { + public: + virtual + ~holder () {} + + virtual holder* + clone () const = 0; + + virtual std::type_info& + type_info () const = 0; + }; + + template <typename X> + class holder_impl: public holder + { + public: + holder_impl (X const& x) + : x_ (x) + { + } + + virtual holder_impl* + clone () const + { + return new holder_impl (x_); + } + + virtual std::type_info& + type_info () const + { + return typeid (x_); + } + + X const& + value () const + { + return x_; + } + + X& + value () + { + return x_; + } + + private: + X x_; + }; + + private: + std::auto_ptr<holder> holder_; + }; + } +} + +#endif // CUTL_CONTAINER_ANY_HXX diff --git a/cutl/container/graph.hxx b/cutl/container/graph.hxx new file mode 100644 index 0000000..9d1c716 --- /dev/null +++ b/cutl/container/graph.hxx @@ -0,0 +1,157 @@ +// file : cutl/container/graph.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2009 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +#ifndef CUTL_CONTAINER_GRAPH_HXX +#define CUTL_CONTAINER_GRAPH_HXX + +#include <map> +#include <cutl/shared-ptr.hxx> + +namespace cutl +{ + namespace container + { + template <typename N, typename E> + class graph + { + public: + typedef N node_base; + typedef E edge_base; + + struct no_edge {}; + + 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&); + + // template <typename T> + // void + // delete_node (T& node); + + public: + template <typename T, typename L, typename R> + T& + new_edge (L&, R&); + + template <typename T, typename L, typename R, + typename A0> + T& + new_edge (L&, R&, A0 const&); + + template <typename T, typename L, typename R, + typename A0, typename A1> + T& + new_edge (L&, R&, A0 const&, A1 const&); + + template <typename T, typename L, typename R, + typename A0, typename A1, typename A2> + T& + new_edge (L&, R&, A0 const&, A1 const&, A2 const&); + + template <typename T, typename L, typename R, + typename A0, typename A1, typename A2, typename A3> + T& + new_edge (L&, R&, A0 const&, A1 const&, A2 const&, A3 const&); + + template <typename T, typename L, typename R, + typename A0, typename A1, typename A2, typename A3, + typename A4> + T& + new_edge (L&, R&, A0 const&, A1 const&, A2 const&, A3 const&, + A4 const&); + + template <typename T, typename L, typename R, + typename A0, typename A1, typename A2, typename A3, + typename A4, typename A5> + T& + new_edge (L&, R&, A0 const&, A1 const&, A2 const&, A3 const&, + A4 const&, A5 const&); + + public: + template <typename T, typename L, typename R> + void + delete_edge (L&, R&, T& edge); + + public: + graph () {} + + private: + graph (graph const&); + + graph& + operator= (graph const&); + + protected: + typedef shared_ptr<node_base> node_ptr; + typedef shared_ptr<edge_base> edge_ptr; + + typedef std::map<node_base*, node_ptr> nodes; + typedef std::map<edge_base*, edge_ptr> edges; + + nodes nodes_; + edges edges_; + }; + } +} + +#include <cutl/container/graph.txx> + +#endif // CUTL_CONTAINER_GRAPH_HXX diff --git a/cutl/container/graph.txx b/cutl/container/graph.txx new file mode 100644 index 0000000..534b0ac --- /dev/null +++ b/cutl/container/graph.txx @@ -0,0 +1,315 @@ +// file : cutl/container/graph.txx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2009 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +namespace cutl +{ + namespace container + { + + // Nodes. + // + + template <typename N, typename E> + template <typename T> + T& graph<N, E>:: + new_node () + { + shared_ptr<T> node (new (shared) 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) + { + shared_ptr<T> node (new (shared) 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) + { + shared_ptr<T> node (new (shared) 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) + { + shared_ptr<T> node (new (shared) 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) + { + shared_ptr<T> node (new (shared) 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) + { + shared_ptr<T> node (new (shared) 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) + { + shared_ptr<T> node (new (shared) 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) + { + shared_ptr<T> node (new (shared) 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) + { + shared_ptr<T> node (new (shared) 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) + { + shared_ptr<T> node ( + new (shared) 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) + { + shared_ptr<T> node ( + new (shared) 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 L, typename R> + T& graph<N, E>:: + new_edge (L& l, R& r) + { + shared_ptr<T> edge (new (shared) 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 L, typename R, + typename A0> + T& graph<N, E>:: + new_edge (L& l, R& r, A0 const& a0) + { + shared_ptr<T> edge (new (shared) 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 L, typename R, + typename A0, typename A1> + T& graph<N, E>:: + new_edge (L& l, R& r, A0 const& a0, A1 const& a1) + { + shared_ptr<T> edge (new (shared) 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 L, typename R, + typename A0, typename A1, typename A2> + T& graph<N, E>:: + new_edge (L& l, R& r, A0 const& a0, A1 const& a1, A2 const& a2) + { + shared_ptr<T> edge (new (shared) 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 L, typename R, + typename A0, typename A1, typename A2, typename A3> + T& graph<N, E>:: + new_edge (L& l, R& r, A0 const& a0, A1 const& a1, A2 const& a2, + A3 const& a3) + { + shared_ptr<T> edge (new (shared) 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 L, typename R, + typename A0, typename A1, typename A2, typename A3, + typename A4> + T& graph<N, E>:: + new_edge (L& l, R& r, A0 const& a0, A1 const& a1, A2 const& a2, + A3 const& a3, A4 const& a4) + { + shared_ptr<T> edge (new (shared) 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 L, typename R, + typename A0, typename A1, typename A2, typename A3, + typename A4, typename A5> + T& graph<N, E>:: + new_edge (L& l, R& r, A0 const& a0, A1 const& a1, A2 const& a2, + A3 const& a3, A4 const& a4, A5 const& a5) + { + shared_ptr<T> edge (new (shared) 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 L, typename R> + void graph<N, E>:: + delete_edge (L& l, R& 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 no_edge (); + + 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/cutl/container/pointer-iterator.hxx b/cutl/container/pointer-iterator.hxx new file mode 100644 index 0000000..cc94151 --- /dev/null +++ b/cutl/container/pointer-iterator.hxx @@ -0,0 +1,127 @@ +// file : cutl/container/pointer-iterator.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2009 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +#ifndef CUTL_CONTAINER_POINTER_ITERATOR_HXX +#define CUTL_CONTAINER_POINTER_ITERATOR_HXX + +#include <iterator> // std::iterator_traits + +#include <cutl/meta/remove-p.hxx> + +namespace cutl +{ + namespace container + { + template <typename I> + class pointer_iterator + { + public: + typedef + typename meta::remove_p<typename std::iterator_traits<I>::value_type>::r + value_type; + + typedef + typename std::iterator_traits<I>::iterator_category + iterator_category; + + typedef + typename std::iterator_traits<I>::difference_type + difference_type; + + typedef value_type& reference; + typedef value_type* pointer; + typedef I base_iterator; + + public: + pointer_iterator () + : i_ () // I can be of a pointer type. + { + } + + pointer_iterator (I const& i) + : i_ (i) + { + } + + public: + reference + operator* () const + { + return **i_; + } + + pointer + operator-> () const + { + return *i_; + } + + I const& + base () const + { + return i_; + } + + public: + // Forward iterator requirements. + // + pointer_iterator& + operator++ () + { + ++i_; + return *this; + } + + pointer_iterator + operator++ (int) + { + pointer_iterator r (*this); + ++i_; + return r; + } + + pointer_iterator& + operator-- () + { + --i_; + return *this; + } + + pointer_iterator + operator-- (int) + { + pointer_iterator r (*this); + --i_; + return r; + } + + private: + I i_; + }; + + template <typename I> + inline bool + operator== (pointer_iterator<I> const& a, pointer_iterator<I> const& b) + { + return a.base () == b.base (); + } + + template <typename I> + inline bool + operator!= (pointer_iterator<I> const& a, pointer_iterator<I> const& b) + { + return a.base () != b.base (); + } + + template <typename I> + inline typename pointer_iterator<I>::difference_type + operator- (pointer_iterator<I> const& a, pointer_iterator<I> const& b) + { + return a.base () - b.base (); + } + } +} + +#endif // CUTL_CONTAINER_POINTER_ITERATOR_HXX |