fragment_contents.h

00001 // fragment_contents.h                     -*-c++-*-
00002 //
00003 //   Copyright 2004 Daniel Burrows
00004 //
00005 // A nice way of storing the contents of a fragment.
00006 
00007 #ifndef FRAGMENT_CONTENTS_H
00008 #define FRAGMENT_CONTENTS_H
00009 
00010 #include "curses++.h"
00011 
00012 #include <vector>
00013 
00014 namespace cwidget
00015 {
00020   typedef wchstring fragment_line;
00021 
00030   class fragment_contents
00031   {
00032     class fragment_lines
00033     {
00034       std::vector<fragment_line> v;
00035       mutable int refs;
00036 
00037     public:
00038       class const_iterator;
00039 
00040       class iterator
00041       {
00042         typedef std::vector<fragment_line>::iterator ittype;
00043 
00044         fragment_lines *lines;
00045         ittype i;
00046 
00047       public:
00048         iterator(fragment_lines *_lines, const ittype &_i)
00049           :lines(_lines), i(_i)
00050         { lines->incref(); }
00051 
00052         iterator(const iterator &other)
00053           :lines(other.lines), i(other.i)
00054         { lines->incref(); }
00055 
00056         ~iterator() { lines->decref(); }
00057 
00058         iterator &operator++() { ++i; return *this; }
00059         iterator &operator--() { --i; return *this; }
00060 
00061         fragment_line &operator*() { return *i; }
00062         fragment_line *operator->() { return &*i; }
00063 
00064         iterator &operator=(const iterator &other) {
00065           other.lines->incref();
00066           lines->decref();
00067           lines=other.lines;
00068           i=other.i;
00069 
00070           return *this;
00071         }
00072 
00073         bool operator==(const iterator &other) const {return i==other.i;}
00074         bool operator!=(const iterator &other) const {return i!=other.i;}
00075 
00076         friend class const_iterator;
00077       };
00078 
00079       class const_iterator
00080       {
00081         typedef std::vector<fragment_line>::const_iterator ittype;
00082 
00083         const fragment_lines *lines;
00084         ittype i;
00085 
00086       public:
00087         const_iterator(const fragment_lines *_lines, const ittype &_i)
00088           :lines(_lines), i(_i)
00089         { lines->incref(); }
00090 
00091         const_iterator(const iterator &other)
00092           :lines(other.lines), i(other.i)
00093         {       lines->incref(); }
00094 
00095         const_iterator(const const_iterator &other)
00096           :lines(other.lines), i(other.i)
00097         { lines->incref(); }
00098 
00099         ~const_iterator() { lines->decref(); }
00100 
00101         const_iterator &operator++() { ++i; return *this; }
00102         const_iterator &operator--() { --i; return *this; }
00103 
00104         const fragment_line &operator*() { return *i; }
00105         const fragment_line *operator->() { return &*i; }
00106 
00107         const_iterator &operator=(const const_iterator &other) {
00108           other.lines->incref();
00109           lines->decref();
00110           lines=other.lines;
00111           i=other.i;
00112 
00113           return *this;
00114         }
00115 
00116         const_iterator &operator=(const iterator &other) {
00117           other.lines->incref();
00118           lines->decref();
00119           lines=other.lines;
00120           i=other.i;
00121 
00122           return *this;
00123         }
00124 
00125         bool operator==(const iterator &other) const {return i==other.i;}
00126         bool operator==(const const_iterator &other) const {return i==other.i;}
00127 
00128         bool operator!=(const iterator &other) const {return i!=other.i;}
00129         bool operator!=(const const_iterator &other) const {return i!=other.i;}
00130       };
00131 
00132       fragment_lines():refs(0) {}
00133 
00134       void incref() const {++refs;}
00135       void decref() const {--refs; if(refs==0) delete this;}
00136 
00137       void push_back(const fragment_line &l) {v.push_back(l);}
00138 
00139       iterator begin() {return iterator(this, v.begin());}
00140       const_iterator begin() const {return const_iterator(this, v.begin());}
00141 
00142       iterator end() {return iterator(this, v.end());}
00143       const_iterator end() const {return const_iterator(this, v.end());}
00144 
00145       fragment_line &front() {return v.front();}
00146       const fragment_line &front() const {return v.front();}
00147 
00148       fragment_line &back() {return v.back();}
00149       const fragment_line &back() const {return v.back();}
00150 
00151       fragment_line &operator[](int i) { return v[i]; }
00152       const fragment_line &operator[](int i) const { return v[i]; }
00153 
00154       size_t size() const {return v.size();}
00155     };
00156   public:
00157     typedef fragment_lines::iterator iterator;
00158     typedef fragment_lines::const_iterator const_iterator;
00159 
00161     fragment_contents():lines(new fragment_lines), final_nl(false)
00162     {lines->incref();}
00163 
00165     fragment_contents(const fragment_contents &other)
00166       :lines(other.lines), final_nl(other.final_nl)
00167     {
00168       lines->incref();
00169     }
00170 
00172     ~fragment_contents() {lines->decref();}
00173 
00174     void push_back(const fragment_line &l) {lines->push_back(l);}
00175 
00176     iterator begin() {return lines->begin();}
00177     const_iterator begin() const {return lines->begin();}
00178 
00179     iterator end() {return lines->end();}
00180     iterator end() const {return lines->end();}
00181 
00182     fragment_line &front() {return lines->front();}
00183     const fragment_line &front() const {return lines->front();}
00184 
00185     fragment_line &back() {return lines->back();}
00186     const fragment_line &back() const {return lines->back();}
00187 
00188     size_t size() const {return lines->size();}
00189 
00190     void set_final_nl(bool final_nl_new) {final_nl=final_nl_new;}
00191 
00192     bool get_final_nl() {return final_nl;}
00193 
00194     fragment_line &operator[](int i) { return (*lines)[i]; }
00195     const fragment_line &operator[](int i) const { return (*lines)[i]; }
00196 
00197     fragment_contents &operator=(const fragment_contents &other)
00198     {
00199       other.lines->incref();
00200       lines->decref();
00201 
00202       lines=other.lines;
00203       final_nl=other.final_nl;
00204 
00205       return *this;
00206     }
00207 
00208   private:
00210     fragment_lines *lines;
00211 
00215     bool final_nl;
00216   };
00217 }
00218 
00219 #endif

Generated on Wed Jan 28 07:23:52 2009 for cwidget by  doxygen 1.5.6