cwidget 0.5.16
|
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