From 8e761289a2446367267c6c0d9a26e734f0f78306 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Wed, 16 Dec 2020 20:29:05 +0300 Subject: Get rid of legacy build systems and rename cutl/ to libcutl/ --- libcutl/container/any.hxx | 149 ++++++++++++++ libcutl/container/graph.hxx | 214 ++++++++++++++++++++ libcutl/container/graph.txx | 348 +++++++++++++++++++++++++++++++++ libcutl/container/key.hxx | 70 +++++++ libcutl/container/map-iterator.hxx | 68 +++++++ libcutl/container/multi-index.hxx | 14 ++ libcutl/container/pointer-iterator.hxx | 125 ++++++++++++ 7 files changed, 988 insertions(+) create mode 100644 libcutl/container/any.hxx create mode 100644 libcutl/container/graph.hxx create mode 100644 libcutl/container/graph.txx create mode 100644 libcutl/container/key.hxx create mode 100644 libcutl/container/map-iterator.hxx create mode 100644 libcutl/container/multi-index.hxx create mode 100644 libcutl/container/pointer-iterator.hxx (limited to 'libcutl/container') diff --git a/libcutl/container/any.hxx b/libcutl/container/any.hxx new file mode 100644 index 0000000..a7b1194 --- /dev/null +++ b/libcutl/container/any.hxx @@ -0,0 +1,149 @@ +// file : libcutl/container/any.hxx +// license : MIT; see accompanying LICENSE file + +#ifndef LIBCUTL_CONTAINER_ANY_HXX +#define LIBCUTL_CONTAINER_ANY_HXX + +#include // std::unique_ptr/auto_ptr +#include // std::type_info + +#include + +namespace cutl +{ + namespace container + { + class any + { + public: + struct typing: exception {}; + + public: + any () + { + } + + template + any (X const& x) + : holder_ (new holder_impl (x)) + { + } + + any (any const& x) + : holder_ (x.holder_->clone ()) + { + } + + template + any& + operator= (X const& x) + { + holder_.reset (new holder_impl (x)); + return *this; + } + + any& + operator= (any const& x) + { + holder_.reset (x.holder_->clone ()); + return *this; + } + + public: + template + X& + value () + { + if (holder_impl* p = dynamic_cast*> (holder_.get ())) + return p->value (); + else + throw typing (); + } + + template + X const& + value () const + { + if (holder_impl* p = dynamic_cast*> (holder_.get ())) + return p->value (); + else + throw typing (); + } + + std::type_info const& + type_info () const + { + return holder_->type_info (); + } + + public: + bool + empty () const + { + return holder_.get () == 0; + } + + void + reset () + { + return holder_.reset (); + } + + private: + class LIBCUTL_EXPORT holder + { + public: + virtual + ~holder () {} + + virtual holder* + clone () const = 0; + + virtual std::type_info const& + type_info () const = 0; + }; + + template + 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 const& + type_info () const + { + return typeid (x_); + } + + X const& + value () const + { + return x_; + } + + X& + value () + { + return x_; + } + + private: + X x_; + }; + + private: + std::unique_ptr holder_; + }; + } +} + +#endif // LIBCUTL_CONTAINER_ANY_HXX diff --git a/libcutl/container/graph.hxx b/libcutl/container/graph.hxx new file mode 100644 index 0000000..14be17f --- /dev/null +++ b/libcutl/container/graph.hxx @@ -0,0 +1,214 @@ +// file : libcutl/container/graph.hxx +// license : MIT; see accompanying LICENSE file + +#ifndef LIBCUTL_CONTAINER_GRAPH_HXX +#define LIBCUTL_CONTAINER_GRAPH_HXX + +#include + +#include +#include + +namespace cutl +{ + namespace container + { + struct no_edge: exception {}; + struct no_node: exception {}; + + template + class graph + { + public: + typedef N node_base; + typedef E edge_base; + + public: + template + T& + new_node (); + + template + T& + new_node (A0 const&); + + template + T& + new_node (A0 const&, A1 const&); + + template + T& + new_node (A0 const&, A1 const&, A2 const&); + + template + T& + new_node (A0 const&, A1 const&, A2 const&, A3 const&); + + template + T& + new_node (A0 const&, A1 const&, A2 const&, A3 const&, A4 const&); + + template + T& + new_node (A0 const&, A1 const&, A2 const&, A3 const&, A4 const&, + A5 const&); + + template + T& + new_node (A0 const&, A1 const&, A2 const&, A3 const&, A4 const&, + A5 const&, A6 const&); + + template + T& + new_node (A0 const&, A1 const&, A2 const&, A3 const&, A4 const&, + A5 const&, A6 const&, A7 const&); + + template + T& + new_node (A0 const&, A1 const&, A2 const&, A3 const&, A4 const&, + A5 const&, A6 const&, A7 const&, A8 const&); + + template + T& + new_node (A0 const&, A1 const&, A2 const&, A3 const&, A4 const&, + A5 const&, A6 const&, A7 const&, A8 const&, A9 const&); + + // Non-const versions. + // + template + T& + new_node (A0&); + + template + T& + new_node (A0&, A1&); + + template + T& + new_node (A0&, A1&, A2&); + + public: + template + T& + new_edge (L&, R&); + + template + T& + new_edge (L&, R&, A0 const&); + + template + T& + new_edge (L&, R&, A0 const&, A1 const&); + + template + T& + new_edge (L&, R&, A0 const&, A1 const&, A2 const&); + + template + T& + new_edge (L&, R&, A0 const&, A1 const&, A2 const&, A3 const&); + + template + T& + new_edge (L&, R&, A0 const&, A1 const&, A2 const&, A3 const&, + A4 const&); + + template + T& + new_edge (L&, R&, A0 const&, A1 const&, A2 const&, A3 const&, + A4 const&, A5 const&); + + // Functions to reset edge's nodes. + // + public: + template + void + reset_left_node (TE& edge, TN& node) + { + edge.set_left_node (node); + } + + template + void + reset_right_node (TE& edge, TN& node) + { + edge.set_right_node (node); + } + + // Functions to add edges to a node. + // + public: + template + void + add_edge_left (TN& node, TE& edge) + { + node.add_edge_left (edge); + } + + template + 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 + void + delete_edge (L& left_node, R& right_node, T& edge); + + void + delete_node (node_base& node) + { + if (nodes_.erase (&node) == 0) + throw no_node (); + } + + public: + graph () {} + + private: + graph (graph const&); + + graph& + operator= (graph const&); + + protected: + typedef shared_ptr node_ptr; + typedef shared_ptr edge_ptr; + + typedef std::map nodes; + typedef std::map edges; + + nodes nodes_; + edges edges_; + }; + } +} + +#include + +#endif // CUTL_CONTAINER_GRAPH_HXX diff --git a/libcutl/container/graph.txx b/libcutl/container/graph.txx new file mode 100644 index 0000000..404c115 --- /dev/null +++ b/libcutl/container/graph.txx @@ -0,0 +1,348 @@ +// file : libcutl/container/graph.txx +// license : MIT; see accompanying LICENSE file + +namespace cutl +{ + namespace container + { + + // Nodes. + // + + template + template + T& graph:: + new_node () + { + shared_ptr node (new (shared) T); + nodes_[node.get ()] = node; + + return *node; + } + + + template + template + T& graph:: + new_node (A0 const& a0) + { + shared_ptr node (new (shared) T (a0)); + nodes_[node.get ()] = node; + + return *node; + } + + + template + template + T& graph:: + new_node (A0 const& a0, A1 const& a1) + { + shared_ptr node (new (shared) T (a0, a1)); + nodes_[node.get ()] = node; + + return *node; + } + + template + template + T& graph:: + new_node (A0 const& a0, A1 const& a1, A2 const& a2) + { + shared_ptr node (new (shared) T (a0, a1, a2)); + nodes_[node.get ()] = node; + + return *node; + } + + template + template + T& graph:: + new_node (A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3) + { + shared_ptr node (new (shared) T (a0, a1, a2, a3)); + nodes_[node.get ()] = node; + + return *node; + } + + template + template + T& graph:: + new_node (A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, + A4 const& a4) + { + shared_ptr node (new (shared) T (a0, a1, a2, a3, a4)); + nodes_[node.get ()] = node; + + return *node; + } + + template + template + T& graph:: + new_node (A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, + A4 const& a4, A5 const& a5) + { + shared_ptr node (new (shared) T (a0, a1, a2, a3, a4, a5)); + nodes_[node.get ()] = node; + + return *node; + } + + template + template + T& graph:: + 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 node (new (shared) T (a0, a1, a2, a3, a4, a5, a6)); + nodes_[node.get ()] = node; + + return *node; + } + + template + template + T& graph:: + 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 node (new (shared) T (a0, a1, a2, a3, a4, a5, a6, a7)); + nodes_[node.get ()] = node; + + return *node; + } + + + template + template + T& graph:: + 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 node ( + new (shared) T (a0, a1, a2, a3, a4, a5, a6, a7, a8)); + nodes_[node.get ()] = node; + + return *node; + } + + + template + template + T& graph:: + 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 node ( + new (shared) T (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); + nodes_[node.get ()] = node; + + return *node; + } + + // Non-const versions. + // + template + template + T& graph:: + new_node (A0& a0) + { + shared_ptr node (new (shared) T (a0)); + nodes_[node.get ()] = node; + + return *node; + } + + + template + template + T& graph:: + new_node (A0& a0, A1& a1) + { + shared_ptr node (new (shared) T (a0, a1)); + nodes_[node.get ()] = node; + + return *node; + } + + template + template + T& graph:: + new_node (A0& a0, A1& a1, A2& a2) + { + shared_ptr node (new (shared) T (a0, a1, a2)); + nodes_[node.get ()] = node; + + return *node; + } + + // Edges. + // + + template + template + T& graph:: + new_edge (L& l, R& r) + { + shared_ptr 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 + template + T& graph:: + new_edge (L& l, R& r, A0 const& a0) + { + shared_ptr 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 + template + T& graph:: + new_edge (L& l, R& r, A0 const& a0, A1 const& a1) + { + shared_ptr 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 + template + T& graph:: + new_edge (L& l, R& r, A0 const& a0, A1 const& a1, A2 const& a2) + { + shared_ptr 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 + template + T& graph:: + new_edge (L& l, R& r, A0 const& a0, A1 const& a1, A2 const& a2, + A3 const& a3) + { + shared_ptr 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 + template + T& graph:: + new_edge (L& l, R& r, A0 const& a0, A1 const& a1, A2 const& a2, + A3 const& a3, A4 const& a4) + { + shared_ptr 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 + template + T& graph:: + 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 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 + template + void graph:: + 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/libcutl/container/key.hxx b/libcutl/container/key.hxx new file mode 100644 index 0000000..aee63cf --- /dev/null +++ b/libcutl/container/key.hxx @@ -0,0 +1,70 @@ +// file : libcutl/container/key.hxx +// license : MIT; see accompkeying LICENSE file + +#ifndef LIBCUTL_CONTAINER_KEY_HXX +#define LIBCUTL_CONTAINER_KEY_HXX + +namespace cutl +{ + namespace container + { + // A modifiable map key wrapper that can be used to implement multi- + // index containers, as discussed in the following post: + // + // http://www.codesynthesis.com/~boris/blog/2012/09/11/emulating-boost-multi-index-with-std-containers/ + // + template + struct key; + + template + struct key + { + mutable const T1* p1; + + key (): p1 (0) {} + key (const T1& r1): p1 (&r1) {} + void assign (const T1& r1) const {p1 = &r1;} + + bool operator< (const key& x) const {return *p1 < *x.p1;} + }; + + template + struct key + { + mutable const T1* p1; + mutable const T2* p2; + + key (): p1 (0), p2 (0) {} + key (const T1& r1, const T2& r2): p1 (&r1), p2 (&r2) {} + void assign (const T1& r1, const T2& r2) const {p1 = &r1; p2 = &r2;} + + bool operator< (const key& x) const + { + return *p1 < *x.p1 || (!(*x.p1 < *p1) && *p2 < *x.p2); + } + }; + + template + struct key + { + mutable const T1* p1; + mutable const T2* p2; + mutable const T3* p3; + + key (): p1 (0), p2 (0), p3 (0) {} + key (const T1& r1, const T2& r2, const T3& r3) + : p1 (&r1), p2 (&r2) , p3 (&r3) {} + void assign (const T1& r1, const T2& r2, const T3& r3) const + {p1 = &r1; p2 = &r2; p3 = &r3;} + + bool operator< (const key& x) const + { + return (*p1 < *x.p1 || + (!(*x.p1 < *p1) && (*p2 < *x.p2 || + (!(*x.p2 < *p2) && *p3 < *x.p3)))); + } + }; + } +} + +#endif // LIBCUTL_CONTAINER_KEY_HXX diff --git a/libcutl/container/map-iterator.hxx b/libcutl/container/map-iterator.hxx new file mode 100644 index 0000000..a5b65e8 --- /dev/null +++ b/libcutl/container/map-iterator.hxx @@ -0,0 +1,68 @@ +// file : libcutl/container/map-iterator.hxx +// license : MIT; see accompanying LICENSE file + +#ifndef LIBCUTL_CONTAINER_MAP_ITERATOR_HXX +#define LIBCUTL_CONTAINER_MAP_ITERATOR_HXX + +namespace cutl +{ + namespace container + { + // Map iterator adapter that can be used to implement multi-index + // containers, as discussed in the following post: + // + // http://www.codesynthesis.com/~boris/blog/2012/09/11/emulating-boost-multi-index-with-std-containers/ + // + template + struct map_iterator: M::iterator + { + typedef typename M::iterator base_iterator; + typedef typename M::value_type::second_type value_type; + typedef value_type* pointer; + typedef value_type& reference; + + map_iterator () {} + map_iterator (base_iterator i): base_iterator (i) {} + + reference + operator* () const + { + return base_iterator::operator* ().second; + } + + pointer + operator-> () const + { + return &base_iterator::operator-> ()->second; + } + }; + + template + struct map_const_iterator: M::const_iterator + { + typedef typename M::iterator base_iterator; + typedef typename M::const_iterator base_const_iterator; + typedef const typename M::value_type::second_type value_type; + typedef value_type* pointer; + typedef value_type& reference; + + map_const_iterator () {} + map_const_iterator (base_iterator i): base_const_iterator (i) {} + map_const_iterator (base_const_iterator i): base_const_iterator (i) {} + + reference + operator* () const + { + return base_const_iterator::operator* ().second; + } + + pointer + operator-> () const + { + return &base_const_iterator::operator-> ()->second; + } + }; + } +} + +#endif // LIBCUTL_CONTAINER_MAP_ITERATOR_HXX diff --git a/libcutl/container/multi-index.hxx b/libcutl/container/multi-index.hxx new file mode 100644 index 0000000..455b57c --- /dev/null +++ b/libcutl/container/multi-index.hxx @@ -0,0 +1,14 @@ +// file : libcutl/container/multi-index.hxx +// license : MIT; see accompanying LICENSE file + +#ifndef LIBCUTL_CONTAINER_MULTI_INDEX_HXX +#define LIBCUTL_CONTAINER_MULTI_INDEX_HXX + +// Multi-index containers support. See the following post for details: +// +// http://www.codesynthesis.com/~boris/blog/2012/09/11/emulating-boost-multi-index-with-std-containers/ +// +#include +#include + +#endif // LIBCUTL_CONTAINER_MULTI_INDEX_HXX diff --git a/libcutl/container/pointer-iterator.hxx b/libcutl/container/pointer-iterator.hxx new file mode 100644 index 0000000..586e15b --- /dev/null +++ b/libcutl/container/pointer-iterator.hxx @@ -0,0 +1,125 @@ +// file : libcutl/container/pointer-iterator.hxx +// license : MIT; see accompanying LICENSE file + +#ifndef LIBCUTL_CONTAINER_POINTER_ITERATOR_HXX +#define LIBCUTL_CONTAINER_POINTER_ITERATOR_HXX + +#include // std::iterator_traits + +#include + +namespace cutl +{ + namespace container + { + template + class pointer_iterator + { + public: + typedef + typename meta::remove_p::value_type>::r + value_type; + + typedef + typename std::iterator_traits::iterator_category + iterator_category; + + typedef + typename std::iterator_traits::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 + inline bool + operator== (pointer_iterator const& a, pointer_iterator const& b) + { + return a.base () == b.base (); + } + + template + inline bool + operator!= (pointer_iterator const& a, pointer_iterator const& b) + { + return a.base () != b.base (); + } + + template + inline typename pointer_iterator::difference_type + operator- (pointer_iterator const& a, pointer_iterator const& b) + { + return a.base () - b.base (); + } + } +} + +#endif // LIBCUTL_CONTAINER_POINTER_ITERATOR_HXX -- cgit v1.1