00001
00002
00003 #include "cppscript"
00004 #include "dynamic/extensions.hpp"
00005 #include "wrap_cpp_container.hpp"
00006
00007 #include <set>
00008
00009 static_call( register_pickle_type( cmp_set, set() ) );
00010
00011 using internal::nonroot_var;
00012
00013
00014 namespace
00015 {
00016 typedef nonroot_var value_type;
00017
00018 struct comparator
00019 {
00020 bool operator()(const nonroot_var & a, const nonroot_var & b) const
00021 {
00022 return a.ref().impl().compare(b.ref()) == cmp_lt;
00023 }
00024 };
00025
00026
00027 struct set_traits
00028 {
00029 typedef nonroot_var value_type;
00030
00031 typedef std::set<nonroot_var, comparator> container;
00032
00033 static const var & key(const var & v)
00034 {
00035 return v;
00036 }
00037
00038 static var key(const value_type & i)
00039 {
00040 return i.get();
00041 }
00042
00043 static var value(const value_type & i)
00044 {
00045 return i.get();
00046 }
00047
00048 static const var_cmp_index comparison_index = cmp_set;
00049
00050 static const char * class_name()
00051 {
00052 return "set";
00053 }
00054
00055 static const char * iterator_class_name()
00056 {
00057 return "set_iterator";
00058 }
00059
00060 static var deref(const nonroot_var & r)
00061 {
00062 return r.get();
00063 }
00064
00065 static void mark_reachable(const nonroot_var & v, gc::garbage_collector & gc)
00066 {
00067 v.ref().impl().mark_reachable(gc);
00068 }
00069 };
00070 }
00071
00072 namespace dynamic
00073 {
00074 namespace types
00075 {
00077 class set_impl : public dynamic::internal::wrap_cpp_container<set_traits>
00078 {
00079 public:
00080 var call(const var & a)
00081 {
00082 invalidate_iterators();
00083 m_data.insert(a);
00084 return this;
00085 }
00086
00087 var front()
00088 {
00089 return this->m_data.empty() ? var() : this->m_data.begin()->get();
00090 }
00091
00092 var back()
00093 {
00094 return this->m_data.empty() ? var() : this->m_data.rbegin()->get();
00095 }
00096
00097 void output(dynamic::ostream & os)
00098 {
00099 os << '{';
00100
00101 bool first=true;
00102
00103 for(set_traits::container::iterator i=this->m_data.begin();
00104 i!=this->m_data.end();
00105 ++i)
00106 {
00107 if(first)
00108 first=false;
00109 else
00110 os << ',';
00111 i->ref().impl().output(os);
00112 }
00113
00114 os << '}';
00115 }
00116
00117 void output(dynamic::wostream & os)
00118 {
00119 os << L'{';
00120
00121 bool first=true;
00122
00123 for(set_traits::container::iterator i=this->m_data.begin();
00124 i!=this->m_data.end();
00125 ++i)
00126 {
00127 if(first) first=false;
00128 else os << L',';
00129 i->ref().impl().output(os);
00130 }
00131
00132 os << L'}';
00133 }
00134
00135 void erase(const var & a)
00136 {
00137 invalidate_iterators();
00138 m_data.erase(a);
00139 }
00140
00141 bool contains(const var & a)
00142 {
00143 return m_data.find(a) != m_data.end();
00144 }
00145
00146 var clone()
00147 {
00148 return new set_impl(*this);
00149 }
00150
00151 int max_args()
00152 {
00153 return 1;
00154 }
00155
00156 void insert(const var & a)
00157 {
00158 invalidate_iterators();
00159 m_data.insert(a);
00160 }
00161
00162 var op_add(const var & other)
00163 {
00164 return clone() += other;
00165 }
00166
00167 var op_sub(const var & other)
00168 {
00169 return clone() -= other;
00170 }
00171
00172 typedef set_traits::container::iterator iterator;
00173
00174 var op_mul(const var & other)
00175 {
00176 var s = set();
00177
00178 for(iterator i=this->m_data.begin();
00179 i!=this->m_data.end();
00180 ++i)
00181 {
00182 if(other.contains(i->ref()))
00183 s.insert(i->ref());
00184 }
00185 return s;
00186 }
00187
00188 void assign_add(const var & other)
00189 {
00190 foreach(i, other) insert(i);
00191 }
00192
00193 void mixin(const var & other)
00194 {
00195 assign_add(other);
00196 }
00197
00198 void assign_sub(const var & other)
00199 {
00200 foreach(i, other) erase(i);
00201 }
00202
00203 void assign_mul(const var & other)
00204 {
00205 for(iterator i=this->m_data.begin();
00206 i!=this->m_data.end();
00207 )
00208 {
00209 if(!other.contains(i->ref()))
00210 {
00211 iterator to_delete = i;
00212 ++i;
00213 m_data.erase(to_delete);
00214 }
00215 else
00216 {
00217 ++i;
00218 }
00219 }
00220 }
00221
00222 void pickle(pickler & p)
00223 {
00224 p.write_object_type(cmp_set);
00225 p.write_int(int(m_data.size()));
00226 for(iterator i=m_data.begin(); i!=m_data.end(); ++i)
00227 {
00228 p.write_object(i->ref());
00229 }
00230 }
00231
00232 void unpickle(unpickler & p)
00233 {
00234 int size = p.read_int();
00235 for(int i=0; i<size; ++i)
00236 {
00237 m_data.insert( p.read_object() );
00238 }
00239 }
00240 };
00241 }
00242 }
00243
00244
00245 var dynamic::set()
00246 {
00247 return new types::set_impl();
00248 }
00249
00250
00251 var dynamic::set(const var & a)
00252 {
00253 return set()(a);
00254 }
00255
00256
00257 var dynamic::set(const var & a0, const var & a1)
00258 {
00259 return set(a0)(a1);
00260 }
00261
00262
00263 var dynamic::set(const var & a0, const var & a1, const var & a2)
00264 {
00265 return set(a0)(a1)(a2);
00266 }
00267
00268
00269 var dynamic::set(const var & a0, const var & a1, const var & a2, const var & a3)
00270 {
00271 return set(a0)(a1)(a2)(a3);
00272 }
00273
00274
00275 var dynamic::set(const var & a0, const var & a1, const var & a2, const var & a3, const var & a4)
00276 {
00277 return set(a0)(a1)(a2)(a3)(a4);
00278 }
00279
00280
00281 var dynamic::set(const var & a0, const var & a1, const var & a2, const var & a3, const var & a4, const var & a5)
00282 {
00283 return set(a0)(a1)(a2)(a3)(a4)(a5);
00284 }
00285
00286
00287 var dynamic::set(const var & a0, const var & a1, const var & a2, const var & a3, const var & a4, const var & a5, const var & a6)
00288 {
00289 return set(a0)(a1)(a2)(a3)(a4)(a5)(a6);
00290 }
00291
00292
00293 var dynamic::set(const var & a0, const var & a1, const var & a2, const var & a3, const var & a4, const var & a5, const var & a6, const var & a7)
00294 {
00295 return set(a0)(a1)(a2)(a3)(a4)(a5)(a6)(a7);
00296 }
00297
00298
00299 var dynamic::set(const var & a0, const var & a1, const var & a2, const var & a3, const var & a4, const var & a5, const var & a6, const var & a7, const var & a8)
00300 {
00301 return set(a0)(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8);
00302 }
00303
00304
00305 var dynamic::set(const var & a0, const var & a1, const var & a2, const var & a3, const var & a4, const var & a5, const var & a6, const var & a7, const var & a8, const var & a9)
00306 {
00307 return set(a0)(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(a9);
00308 }
00309
00310
00311 var dynamic::set_from(const var & s)
00312 {
00313 var r = set();
00314 foreach(i, s) r.insert(i);
00315 return r;
00316 }