00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00035
00036 #ifndef GROOVX_TCL_LIST_H_UTC20050628162420_DEFINED
00037 #define GROOVX_TCL_LIST_H_UTC20050628162420_DEFINED
00038
00039 #include "tcl/conversions.h"
00040 #include "tcl/obj.h"
00041
00042 #include "rutz/shared_ptr.h"
00043
00044 namespace tcl
00045 {
00046 class list;
00047
00048 tcl::list aux_convert_to(Tcl_Obj* obj, tcl::list*);
00049 tcl::obj aux_convert_from(tcl::list list_value);
00050 }
00051
00053
00058
00059
00060 class tcl::list
00061 {
00062 public:
00064 list();
00065
00066 list(const tcl::obj& x);
00067
00068 list(const list& other) :
00069 m_list_obj(other.m_list_obj),
00070 m_elements(other.m_elements),
00071 m_length(other.m_length)
00072 {}
00073
00074 list& operator=(const list& other)
00075 {
00076 m_list_obj = other.m_list_obj;
00077 m_elements = other.m_elements;
00078 m_length = other.m_length;
00079 return *this;
00080 }
00081
00082 tcl::obj as_obj() const { return m_list_obj; }
00083
00085 Tcl_Obj* at(unsigned int index) const;
00086
00088 Tcl_Obj* operator[](unsigned int index) const
00089 {
00090 update(); return m_elements[index];
00091 }
00092
00093 Tcl_Obj* const* elements() const
00094 {
00095 update(); return m_elements;
00096 }
00097
00098 template <class T>
00099 inline T get(unsigned int index, T* =0) const;
00100
00101 unsigned int size() const { update(); return m_length; }
00102 unsigned int length() const { update(); return m_length; }
00103
00104 template <class T>
00105 void append(T t) { do_append(tcl::convert_from(t), 1); }
00106
00107 template <class T>
00108 void append(T t, unsigned int times)
00109 {
00110 do_append(tcl::convert_from(t), times);
00111 }
00112
00113 template <class Itr>
00114 void append_range(Itr itr, Itr end)
00115 {
00116 while (itr != end)
00117 {
00118 append(*itr);
00119 ++itr;
00120 }
00121 }
00122
00123 class iterator_base;
00124 template <class T> class iterator;
00125
00126 template <class T>
00127 iterator<T> begin(T* =0);
00128
00129 template <class T>
00130 iterator<T> end(T* =0);
00131
00133 class appender
00134 {
00135 tcl::list& m_list_obj;
00136 public:
00137 appender(tcl::list& x) : m_list_obj(x) {}
00138
00139 template <class T>
00140 appender& operator=(const T& val)
00141 { m_list_obj.append(val); return *this; }
00142
00143 appender& operator*() { return *this; }
00144 appender& operator++() { return *this; }
00145 appender operator++(int) { return *this; }
00146 };
00147
00148 appender back_appender() { return appender(*this); }
00149
00151 static unsigned int get_obj_list_length(Tcl_Obj* obj);
00152
00153 private:
00154 void do_append(const tcl::obj& obj, unsigned int times);
00155
00156 void update() const
00157 {
00158 if (m_elements==0)
00159 split();
00160 }
00161
00162 void split() const;
00163
00164 void invalidate() { m_elements = 0; m_length = 0; }
00165
00166 mutable tcl::obj m_list_obj;
00167 mutable Tcl_Obj** m_elements;
00168 mutable unsigned int m_length;
00169 };
00170
00171
00173
00178
00179
00180 class tcl::list::iterator_base
00181 {
00182 protected:
00183
00184 ~iterator_base() {}
00185
00186 public:
00187 typedef int difference_type;
00188
00189 enum position { BEGIN, END };
00190
00191 iterator_base(const list& owner, position start_pos = BEGIN) :
00192 m_list_obj(owner),
00193 m_index(start_pos == BEGIN ? 0 : owner.length())
00194 {}
00195
00196 iterator_base(Tcl_Obj* x, position start_pos = BEGIN) :
00197 m_list_obj(x),
00198 m_index(start_pos == BEGIN ? 0 : m_list_obj.length())
00199 {}
00200
00201
00202
00203 iterator_base& operator++()
00204 { ++m_index; return *this; }
00205
00206 iterator_base operator++(int)
00207 { iterator_base temp(*this); ++m_index; return temp; }
00208
00209 difference_type operator-(const iterator_base& other) const
00210 {
00211 if (this->m_index > other.m_index)
00212 return int(this->m_index - other.m_index);
00213 else
00214 return -(int(other.m_index - this->m_index));
00215 }
00216
00217 bool operator==(const iterator_base& other) const
00218 { return m_index == other.m_index; }
00219
00220 bool operator!=(const iterator_base& other) const
00221 { return !operator==(other); }
00222
00223 bool is_valid() const
00224 { return m_index < m_list_obj.length(); }
00225
00226 bool has_more() const
00227 { return m_index < (m_list_obj.length()-1); }
00228
00229 bool nelems() const
00230 { return m_list_obj.length(); }
00231
00232 protected:
00233 Tcl_Obj* current() const
00234 { return m_list_obj.at(m_index); }
00235
00236 private:
00237 list m_list_obj;
00238 unsigned int m_index;
00239
00240 };
00241
00242
00244
00251
00252
00253 template <class T>
00254 class tcl::list::iterator : public tcl::list::iterator_base
00255 {
00256
00257
00258 mutable rutz::shared_ptr<const T> m_current;
00259
00260 public:
00261 iterator(const list& owner, position start_pos = BEGIN) :
00262 iterator_base(owner, start_pos), m_current() {}
00263
00264 iterator(Tcl_Obj* x, position start_pos = BEGIN) :
00265 iterator_base(x, start_pos), m_current() {}
00266
00267 typedef T value_type;
00268
00269 const T& operator*() const
00270 {
00271 m_current.reset(new T(tcl::convert_to<T>(current())));
00272 return *m_current;
00273 }
00274 };
00275
00276
00278
00279
00280
00282
00283 #include "tcl/conversions.h"
00284
00285 template <class T>
00286 inline T tcl::list::get(unsigned int index, T* ) const
00287 {
00288 return tcl::convert_to<T>(at(index));
00289 }
00290
00291 template <class T>
00292 inline tcl::list::iterator<T> tcl::list::begin(T* )
00293 {
00294 return iterator<T>(*this, iterator_base::BEGIN);
00295 }
00296
00297 template <class T>
00298 inline tcl::list::iterator<T> tcl::list::end(T* )
00299 {
00300 return iterator<T>(*this, iterator_base::END);
00301 }
00302
00303 static const char __attribute__((used)) vcid_groovx_tcl_list_h_utc20050628162420[] = "$Id: list.h 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00304 #endif // !GROOVX_TCL_LIST_H_UTC20050628162420_DEFINED