/* * utilities... */ #ifndef UTIL_H #define UTIL_H #include #include #include #include #include #include using namespace std; /* these defines belongs into config.h */ #define abstract = 0 #define t_no noexcept #define t_err // can only throw error inline bool equal (double a, double b) { return abs (a - b) <= a * 1e-6; } template class shared; template bool operator <(const shared &a, const shared &b) t_no; template class shared { struct storage : T { int shared; storage () t_no : shared(0) {}; storage (const storage &s) t_no : T(s), shared(0) {}; }; protected: mutable storage *obj; void unshare() const t_no { if (obj->shared) { obj->shared--; obj = new storage(*obj); } }; public: typedef typename T::value_type data_type; typedef typename T::const_iterator const_iterator; typedef typename T::iterator iterator; typedef typename T::const_reference const_reference; typedef typename T::reference reference; typedef typename T::size_type size_type; shared() t_no { obj = new storage; }; shared(const shared &v) t_no { obj = v.obj; obj->shared++; }; shared &operator =(const shared &v) t_no { v.obj->shared++; if (obj->shared) obj->shared--; else delete obj; obj = v.obj; return *this; }; ~shared() t_no { if (obj->shared) obj->shared--; else delete obj; }; void erase () t_no { if (obj->shared) { obj->shared--; obj = new storage; } else obj->erase (obj->begin(), obj->end ()); }; const_iterator begin () const t_no { return obj->begin (); }; const_iterator end () const t_no { return obj->end (); }; iterator begin () t_no { unshare (); return obj->begin (); }; iterator end () t_no { unshare (); return obj->end (); }; size_type size () const t_no { return obj->size (); }; bool empty () const t_no { return obj->empty (); }; const T& operator ->() const t_no { return *obj; }; T& operator ->() t_no { unshare (); return *obj; }; const T& operator * () const t_no { return *obj; }; T& operator * () t_no { unshare (); return *obj; }; operator const T& () const t_no { return *obj; }; operator T& () t_no { unshare (); return *obj; }; void insert (iterator a, iterator b, iterator c) t_no { unshare (); obj->insert (a, b, c); }; friend bool operator < <>(const shared &a, const shared &b) t_no; }; template bool operator <(const shared &a, const shared &b) t_no { if (a.obj == b.obj) return false; else if (a.size () < b.size ()) return true; else if (a.size () == b.size ()) { typename shared::const_iterator i, j; for (i = a.begin (), j = b.begin (); i != a.end (); ++i, ++j) if (*i < *j) return true; } return false; } template struct shared_vector : public shared< vector > { T &operator [](int idx) t_no { shared< vector >::unshare (); return shared< vector >::obj->begin()+idx; }; void push_back (typename shared_vector::const_reference arg) t_no { shared< vector >::unshare (); shared< vector >::obj->push_back (arg); }; }; struct error : exception { string msg; const char *what () const t_no { return msg.c_str (); }; error (const string &s) t_no : msg(s) {}; error (const string &s, int line) t_no; error (const string &s, const class module &m) t_no; ~error () t_no { }; template error &operator <<(const T &s) t_no { msg.append (s); return *this; }; }; inline ostream &operator <<(ostream &o, const error &e) t_no { return o << e.what () << endl; } #endif