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