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 class IsNamePrefix : public UnaryShapeRootPred {
00202 public:
00203 std::string name;
00204 size_t n;
00205 explicit IsNamePrefix(std::string _name) : UnaryShapeRootPred(), name(_name), n(_name.size()) {}
00206 bool operator()(const ShapeRoot &shape) const {
00207 return strncmp(shape->getName().c_str(), name.c_str(), n) == 0; }
00208 };
00209
00210 class IsLastMatch : public UnaryShapeRootPred {
00211 public:
00212 ShapeRoot wshape;
00213 explicit IsLastMatch(ShapeRoot _wshape) : UnaryShapeRootPred(), wshape(_wshape) {}
00214 bool operator()(const ShapeRoot &lshape) const {
00215 return lshape->getId() == wshape->getLastMatchId(); }
00216 };
00217
00218
00219
00220
00221 template<typename PredType>
00222 ShapeRoot find_if(const std::vector<ShapeRoot> &vec, PredType pred) {
00223 typename std::vector<ShapeRoot>::const_iterator result = find_if(vec.begin(),vec.end(),pred);
00224 if ( result != vec.end() )
00225 return *result;
00226 else
00227 return ShapeRoot();
00228 }
00229
00230
00231 template<class T, typename PredType>
00232 Shape<T> find_if(const std::vector<ShapeRoot> &vec, PredType pred) {
00233 shortcircuit_and<IsType,PredType> tpred(AndPred(IsType(T::getStaticType()),pred));
00234 typename std::vector<ShapeRoot>::const_iterator result = find_if(vec.begin(),vec.end(),tpred);
00235 if ( result != vec.end() )
00236 return ShapeRootTypeConst(*result,T);
00237 else
00238 return Shape<T>();
00239 }
00240
00241
00242 template<class T, typename PredType>
00243 Shape<T> find_if(const std::vector<Shape<T> > &vec, PredType pred) {
00244 typename std::vector<Shape<T> >::const_iterator result = find_if(vec.begin(),vec.end(),pred);
00245 if ( result != vec.end() )
00246 return *result;
00247 else
00248 return Shape<T>();
00249 }
00250
00251
00252 template<class T>
00253 Shape<T> find_if(const std::vector<ShapeRoot> &vec) {
00254 typename std::vector<ShapeRoot>::const_iterator result = find_if(vec.begin(),vec.end(),IsType(T::getStaticType()));
00255 if ( result != vec.end() )
00256 return ShapeRootTypeConst(*result,T);
00257 else
00258 return Shape<T>();
00259 }
00260
00261
00262 ShapeRoot find_shape(const std::vector<ShapeRoot> &vec, const std::string &name);
00263
00264
00265 template<class T>
00266 Shape<T> find_shape(const std::vector<ShapeRoot> &vec, const std::string &name) {
00267 for ( std::vector<ShapeRoot>::const_iterator it = vec.begin();
00268 it != vec.end(); it++ )
00269 if ( (*it)->getType() == T::getStaticType() && (*it)->getName() == name )
00270 return ShapeRootTypeConst(*it,T);
00271 return Shape<T>();
00272 }
00273
00274
00275 template<class T>
00276 std::vector<Shape<T> > select_type(std::vector<ShapeRoot> &vec) {
00277 std::vector<Shape<T> > result(vec.size());
00278 result.clear();
00279 IsType tpred(T::getStaticType());
00280 DO_SHAPEROOTVEC(vec, element, {
00281 if ( tpred(element) ) result.push_back(reinterpret_cast<const Shape<T>&>(element));
00282 });
00283 return result;
00284 }
00285
00286
00287 template<class T, typename PredType>
00288 std::vector<Shape<T> > subset(const std::vector<Shape<T> > &vec, PredType pred) {
00289 std::vector<Shape<T> > result;
00290 remove_copy_if(vec.begin(), vec.end(),
00291 std::back_insert_iterator<std::vector<Shape<T> > >(result),
00292 not1(pred));
00293 return result;
00294 }
00295
00296
00297 template<typename PredType>
00298 std::vector<ShapeRoot> subset(const std::vector<ShapeRoot> &vec, PredType pred) {
00299 std::vector<ShapeRoot> result;
00300 remove_copy_if(vec.begin(), vec.end(),
00301 std::back_insert_iterator<std::vector<ShapeRoot> >(result),
00302 not1(pred));
00303 return result;
00304 }
00305
00306
00307 template<class T, typename PredType>
00308 std::vector<T> subset(const std::vector<ShapeRoot> &vec, PredType pred) {
00309 std::vector<Shape<T> > result;
00310 shortcircuit_and<IsType,PredType> tpred(AndPred(IsType(T::getStaticType()),pred));
00311 remove_copy_if(vec.begin(), vec.end(),
00312 std::back_insert_iterator<std::vector<Shape<T> > >(result),
00313 not1(tpred));
00314 return result;
00315 }
00316
00317 template<class T, typename ComparisonType>
00318 Shape<T> max_element(const std::vector<Shape<T> > &vec, ComparisonType comp) {
00319 typename std::vector<Shape<T> >::const_iterator result = max_element(vec.begin(),vec.end(),comp);
00320 if ( result != vec.end() )
00321 return *result;
00322 else
00323 return Shape<T>();
00324 }
00325
00326 template<typename ComparisonType>
00327 ShapeRoot max_element(const std::vector<ShapeRoot> &vec, ComparisonType comp) {
00328 typename std::vector<ShapeRoot>::const_iterator result = max_element(vec.begin(),vec.end(),comp);
00329 if ( result != vec.end() )
00330 return *result;
00331 else
00332 return ShapeRoot();
00333 }
00334
00335 template<class T, typename ComparisonType>
00336 Shape<T> min_element(const std::vector<Shape<T> > &vec, ComparisonType comp) {
00337 return max_element(vec, not2(comp));
00338 }
00339
00340
00341 template<typename ComparisonType>
00342 ShapeRoot min_element(const std::vector<ShapeRoot> &vec, ComparisonType comp) {
00343 return max_element(vec, not2(comp));
00344 }
00345
00346 template<class T, typename PredType>
00347 std::vector<Shape<T> > stable_sort(const std::vector<Shape<T> > &vec, const PredType& pred) {
00348 std::vector<Shape<T> > result(vec);
00349 stable_sort(result.begin(), result.end(), pred);
00350 return result;
00351 }
00352
00353 template<typename PredType>
00354 std::vector<ShapeRoot> stable_sort(const std::vector<ShapeRoot> &vec, const PredType& pred) {
00355 std::vector<ShapeRoot> result(vec);
00356 stable_sort(result.begin(), result.end(), pred);
00357 return result;
00358 }
00359
00360
00361
00362
00363
00364
00365
00366 #define DIRECTION_PAIR(dir, oppdir) \
00367 class Is##dir : public BinaryShapeRootPred { \
00368 public: \
00369 Is##dir(float distance=0) : dist(distance) {} \
00370 bool operator() (const ShapeRoot&, const ShapeRoot&) const; \
00371 private: \
00372 float dist; \
00373 }; \
00374 \
00375 class Is##dir##This : public UnaryShapeRootPred { \
00376 public: \
00377 Is##dir##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)(s1,s2); } \
00381 private: \
00382 ShapeRoot s2; \
00383 float dist; \
00384 }; \
00385 \
00386 class Is##oppdir : public BinaryShapeRootPred { \
00387 public: \
00388 Is##oppdir(float distance=0) : dist(distance) {} \
00389 bool operator() (const ShapeRoot &s1, const ShapeRoot &s2) const { \
00390 return Is##dir(dist) (s2, s1); } \
00391 private: \
00392 float dist; \
00393 }; \
00394 \
00395 class Is##oppdir##This : public UnaryShapeRootPred { \
00396 public: \
00397 Is##oppdir##This(const ShapeRoot &_s2, float distance=0) : \
00398 UnaryShapeRootPred(), s2(_s2), dist(distance) {} \
00399 bool operator() (const ShapeRoot &s1) const { \
00400 return Is##dir(dist) (s2,s1); } \
00401 private: \
00402 ShapeRoot s2; \
00403 float dist; \
00404 };
00405
00406
00407 DIRECTION_PAIR(LeftOf, RightOf)
00408 DIRECTION_PAIR(Above, Below)
00409
00410 #undef DIRECTION_PAIR
00411
00412 }
00413
00414 #endif