00001
00002 #ifndef INCLUDED_ShapeFuns_h_
00003 #define INCLUDED_ShapeFuns_h_
00004
00005 #include <vector>
00006
00007 #include "Shared/ProjectInterface.h"
00008
00009 #include "ShapeTypes.h"
00010 #include "ShapeRoot.h"
00011
00012 namespace DualCoding {
00013
00014
00015
00016
00017
00018
00019
00020
00021 #define NEW_SHAPE(_name, _type, _value) \
00022 DualCoding::Shape<_type> _name((_value)); \
00023 if ( _name.isValid() ) _name->V(#_name);
00024
00025
00026 #define NEW_SHAPE_N(_name, _type, _value) \
00027 NEW_SHAPE(_name, _type, _value); \
00028 if ( _name.isValid() ) _name->N(#_name);
00029
00030
00031 #define GET_SHAPE(_name, _type, _shapevec) \
00032 DualCoding::Shape<_type> _name(find_shape<_type>(_shapevec,#_name));
00033
00034
00035 #define GET_RENAMED(_new_name, _old_name, _type, _shapevec) \
00036 DualCoding::Shape<_type> _new_name(find_shape<_type>(_shapevec,#_old_name));
00037
00038
00039 #define NEW_SHAPEVEC(_name, _type, _value) \
00040 std::vector<DualCoding::Shape<_type> > _name((_value));
00041
00042
00043 #define NEW_SHAPEROOTVEC(_name, _value) \
00044 std::vector<DualCoding::ShapeRoot> _name((_value));
00045
00046
00047 #define SHAPEVEC_ITERATE(_shapesvec,_type,_var) \
00048 for ( std::vector<DualCoding::Shape<_type> >::iterator _var##_it = _shapesvec.begin(); \
00049 _var##_it != _shapesvec.end(); _var##_it++ ) { \
00050 DualCoding::Shape<_type> &_var = *_var##_it;
00051
00052
00053 #define SHAPENEXT_ITERATE(_shapesvec,_type,_var1,_var2) \
00054 for ( std::vector<DualCoding::Shape<_type> >::iterator _var2##_it = ++std::vector<DualCoding::Shape<_type> >::iterator(_var1##_it); \
00055 _var2##_it != _shapesvec.end(); _var2##_it++ ) { \
00056 DualCoding::Shape<_type> &_var2 = *_var2##_it;
00057
00058
00059 #define SHAPEROOTVEC_ITERATE(_shapesvec,_var) \
00060 for ( std::vector<DualCoding::ShapeRoot>::iterator _var##_it = _shapesvec.begin(); \
00061 _var##_it != _shapesvec.end(); _var##_it++ ) { \
00062 DualCoding::ShapeRoot &_var = *_var##_it;
00063
00064 #define END_ITERATE }
00065
00066
00067 #define DO_SHAPEVEC(_shapesvec,_type,_var,_body) \
00068 for ( std::vector<DualCoding::Shape<_type> >::iterator _var##_it = _shapesvec.begin(); \
00069 _var##_it != _shapesvec.end(); _var##_it++ ) { \
00070 DualCoding::Shape<_type> &_var = *_var##_it; \
00071 _body } \
00072
00073
00074 #define DO_SHAPENEXT(_shapesvec,_type,_var1,_var2,_body) \
00075 for ( std::vector<DualCoding::Shape<_type> >::iterator _var2##_it = ++std::vector<DualCoding::Shape<_type> >::iterator(_var1##_it); \
00076 _var2##_it != _shapesvec.end(); _var2##_it++ ) { \
00077 DualCoding::Shape<_type> &_var2 = *_var2##_it; \
00078 _body }
00079
00080
00081 #define DO_SHAPEROOTVEC(_shapesvec,_var,_body) \
00082 for ( std::vector<DualCoding::ShapeRoot>::iterator _var##_it = _shapesvec.begin(); \
00083 _var##_it != _shapesvec.end(); _var##_it++ ) { \
00084 DualCoding::ShapeRoot &_var = *_var##_it; \
00085 _body }
00086
00087
00088
00089
00090 class UnaryShapeRootPred : public std::unary_function<ShapeRoot, bool> {
00091 public:
00092 virtual ~UnaryShapeRootPred() {}
00093 };
00094
00095
00096 class BinaryShapeRootPred : public std::binary_function<ShapeRoot, ShapeRoot, bool> {
00097 public:
00098 virtual ~BinaryShapeRootPred() {}
00099 };
00100
00101
00102 template <class T>
00103 class UnaryShapePred : public std::unary_function<Shape<T>, bool> {
00104 public:
00105 virtual ~UnaryShapePred() {}
00106 };
00107
00108
00109 template <class T>
00110 class BinaryShapePred : public std::binary_function<Shape<T>, Shape<T>, bool> {
00111 public:
00112 virtual ~BinaryShapePred() {}
00113 };
00114
00115
00116
00117
00118
00119 template<typename PredType1, typename PredType2>
00120 class shortcircuit_and : public std::unary_function<typename PredType1::argument_type,bool> {
00121 public:
00122 PredType1 p1;
00123 PredType2 p2;
00124 shortcircuit_and(PredType1 _p1, PredType2 _p2) :
00125 std::unary_function<typename PredType1::argument_type,bool>(), p1(_p1), p2(_p2) {}
00126 bool operator() (const typename PredType1::argument_type &shape) const {
00127 if ( p1(shape) )
00128 return p2(shape);
00129 else return false;
00130 }
00131 };
00132
00133 template<typename PredType1, typename PredType2>
00134 class shortcircuit_or : public std::unary_function<typename PredType1::argument_type,bool> {
00135 public:
00136 PredType1 p1;
00137 PredType2 p2;
00138 shortcircuit_or(PredType1 _p1, PredType2 _p2) :
00139 std::unary_function<typename PredType1::argument_type,bool>(), p1(_p1), p2(_p2) {}
00140 bool operator() (const typename PredType1::argument_type &shape) const {
00141 if ( p1(shape) )
00142 return true;
00143 else return p2(shape);
00144 }
00145 };
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 template<typename PredType1, typename PredType2>
00159 shortcircuit_and<PredType1,PredType2> AndPred(PredType1 p1, PredType2 p2) {
00160 return shortcircuit_and<PredType1,PredType2>(p1,p2);
00161 }
00162
00163
00164 template<typename PredType1, typename PredType2>
00165 shortcircuit_or<PredType1,PredType2> OrPred(PredType1 p1, PredType2 p2) {
00166 return shortcircuit_or<PredType1,PredType2>(p1,p2);
00167 }
00168
00169
00170
00171
00172
00173 class IsType : public UnaryShapeRootPred {
00174 public:
00175 ShapeType_t type;
00176 explicit IsType(ShapeType_t _type) : UnaryShapeRootPred(), type(_type) {}
00177 bool operator()(const ShapeRoot &shape) const {
00178 return shape->getType() == type; }
00179 };
00180
00181 class IsColor : public UnaryShapeRootPred {
00182 public:
00183 rgb color;
00184 explicit IsColor(int colorIndex) : UnaryShapeRootPred(), color(ProjectInterface::getColorRGB(colorIndex)) {}
00185 explicit IsColor(rgb _color) : UnaryShapeRootPred(), color(_color) {}
00186 explicit IsColor(std::string const &_colorname) : UnaryShapeRootPred(), color(ProjectInterface::getColorRGB(_colorname)) {}
00187 bool operator()(const ShapeRoot &shape) const {
00188 return shape->getColor() == color; }
00189 };
00190
00191 class IsName : public UnaryShapeRootPred {
00192 public:
00193 std::string name;
00194 explicit IsName(std::string _name) : UnaryShapeRootPred(), name(_name) {}
00195 bool operator()(const ShapeRoot &shape) const {
00196
00197 return shape->getName() == name; }
00198 };
00199
00200
00201
00202
00203 template<typename PredType>
00204 ShapeRoot find_if(const std::vector<ShapeRoot> &vec, PredType pred) {
00205 typename std::vector<ShapeRoot>::const_iterator result = find_if(vec.begin(),vec.end(),pred);
00206 if ( result != vec.end() )
00207 return *result;
00208 else
00209 return ShapeRoot();
00210 }
00211
00212
00213 template<class T, typename PredType>
00214 Shape<T> find_if(const std::vector<ShapeRoot> &vec, PredType pred) {
00215 shortcircuit_and<IsType,PredType> tpred(AndPred(IsType(T::getStaticType()),pred));
00216 typename std::vector<ShapeRoot>::const_iterator result = find_if(vec.begin(),vec.end(),tpred);
00217 if ( result != vec.end() )
00218 return ShapeRootTypeConst(*result,T);
00219 else
00220 return Shape<T>();
00221 }
00222
00223
00224 template<class T, typename PredType>
00225 Shape<T> find_if(const std::vector<Shape<T> > &vec, PredType pred) {
00226 typename std::vector<Shape<T> >::const_iterator result = find_if(vec.begin(),vec.end(),pred);
00227 if ( result != vec.end() )
00228 return *result;
00229 else
00230 return Shape<T>();
00231 }
00232
00233
00234 template<class T>
00235 Shape<T> find_if(const std::vector<ShapeRoot> &vec) {
00236 typename std::vector<ShapeRoot>::const_iterator result = find_if(vec.begin(),vec.end(),IsType(T::getStaticType()));
00237 if ( result != vec.end() )
00238 return ShapeRootTypeConst(*result,T);
00239 else
00240 return Shape<T>();
00241 }
00242
00243
00244 template<class T>
00245 Shape<T> find_shape(const std::vector<ShapeRoot> &vec, const std::string &name) {
00246 for ( std::vector<ShapeRoot>::const_iterator it = vec.begin();
00247 it != vec.end(); it++ )
00248 if ( (*it)->getType() == T::getStaticType() && (*it)->getName() == name )
00249 return ShapeRootTypeConst(*it,T);
00250 return Shape<T>();
00251 }
00252
00253
00254 template<class T>
00255 std::vector<Shape<T> > select_type(std::vector<ShapeRoot> &vec) {
00256 std::vector<Shape<T> > result(vec.size());
00257 result.clear();
00258 IsType tpred(T::getStaticType());
00259 DO_SHAPEROOTVEC(vec, element, {
00260 if ( tpred(element) ) result.push_back(reinterpret_cast<const Shape<T>&>(element));
00261 });
00262 return result;
00263 }
00264
00265
00266 template<class T, typename PredType>
00267 std::vector<Shape<T> > subset(const std::vector<Shape<T> > &vec, PredType pred) {
00268 std::vector<Shape<T> > result;
00269 remove_copy_if(vec.begin(), vec.end(),
00270 std::back_insert_iterator<std::vector<Shape<T> > >(result),
00271 not1(pred));
00272 return result;
00273 }
00274
00275
00276 template<typename PredType>
00277 std::vector<ShapeRoot> subset(const std::vector<ShapeRoot> &vec, PredType pred) {
00278 std::vector<ShapeRoot> result;
00279 remove_copy_if(vec.begin(), vec.end(),
00280 std::back_insert_iterator<std::vector<ShapeRoot> >(result),
00281 not1(pred));
00282 return result;
00283 }
00284
00285
00286 template<class T, typename PredType>
00287 std::vector<T> subset(const std::vector<ShapeRoot> &vec, PredType pred) {
00288 std::vector<Shape<T> > result;
00289 shortcircuit_and<IsType,PredType> tpred(AndPred(IsType(T::getStaticType()),pred));
00290 remove_copy_if(vec.begin(), vec.end(),
00291 std::back_insert_iterator<std::vector<Shape<T> > >(result),
00292 not1(tpred));
00293 return result;
00294 }
00295
00296 template<class T, typename ComparisonType>
00297 Shape<T> max_element(const std::vector<Shape<T> > &vec, ComparisonType comp) {
00298 typename std::vector<Shape<T> >::const_iterator result = max_element(vec.begin(),vec.end(),comp);
00299 if ( result != vec.end() )
00300 return *result;
00301 else
00302 return Shape<T>();
00303 }
00304
00305 template<typename ComparisonType>
00306 ShapeRoot max_element(const std::vector<ShapeRoot> &vec, ComparisonType comp) {
00307 typename std::vector<ShapeRoot>::const_iterator result = max_element(vec.begin(),vec.end(),comp);
00308 if ( result != vec.end() )
00309 return *result;
00310 else
00311 return ShapeRoot();
00312 }
00313
00314 template<class T, typename ComparisonType>
00315 Shape<T> min_element(const std::vector<Shape<T> > &vec, ComparisonType comp) {
00316 return max_element(vec, not2(comp));
00317 }
00318
00319
00320 template<typename ComparisonType>
00321 ShapeRoot min_element(const std::vector<ShapeRoot> &vec, ComparisonType comp) {
00322 return max_element(vec, not2(comp));
00323 }
00324
00325 template<class T, typename PredType>
00326 std::vector<Shape<T> > stable_sort(const std::vector<Shape<T> > &vec, PredType pred) {
00327 std::vector<Shape<T> > result(vec);
00328 stable_sort(result.begin(), result.end(), pred);
00329 return result;
00330 }
00331
00332 template<typename PredType>
00333 std::vector<ShapeRoot> stable_sort(const std::vector<ShapeRoot> &vec, PredType pred) {
00334 std::vector<ShapeRoot> result(vec);
00335 stable_sort(result.begin(), result.end(), pred);
00336 return result;
00337 }
00338
00339
00340
00341
00342
00343
00344
00345 #define DIRECTION_PAIR(dir, oppdir) \
00346 class Is##dir : public BinaryShapeRootPred { \
00347 public: \
00348 Is##dir(float distance=0) : dist(distance) {} \
00349 bool operator() (const ShapeRoot&, const ShapeRoot&) const; \
00350 private: \
00351 float dist; \
00352 }; \
00353 \
00354 class Is##dir##This : public UnaryShapeRootPred { \
00355 public: \
00356 Is##dir##This(const ShapeRoot &_s2, float distance=0) : \
00357 UnaryShapeRootPred(), s2(_s2), dist(distance) {} \
00358 bool operator() (const ShapeRoot &s1) const { \
00359 return Is##dir(dist)(s1,s2); } \
00360 private: \
00361 ShapeRoot s2; \
00362 float dist; \
00363 }; \
00364 \
00365 class Is##oppdir : public BinaryShapeRootPred { \
00366 public: \
00367 Is##oppdir(float distance=0) : dist(distance) {} \
00368 bool operator() (const ShapeRoot &s1, const ShapeRoot &s2) const { \
00369 return Is##dir(dist) (s2, s1); } \
00370 private: \
00371 float dist; \
00372 }; \
00373 \
00374 class Is##oppdir##This : public UnaryShapeRootPred { \
00375 public: \
00376 Is##oppdir##This(const ShapeRoot &_s2, float distance=0) : \
00377 UnaryShapeRootPred(), s2(_s2), dist(distance) {} \
00378 bool operator() (const ShapeRoot &s1) const { \
00379 return Is##dir(dist) (s2,s1); } \
00380 private: \
00381 ShapeRoot s2; \
00382 float dist; \
00383 };
00384
00385
00386 DIRECTION_PAIR(LeftOf, RightOf)
00387 DIRECTION_PAIR(Above, Below)
00388
00389 #undef DIRECTION_PAIR
00390
00391 }
00392
00393 #endif