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 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 Shape<_type> _name(find_shape<_type>(_shapevec,#_name));
00033
00034
00035 #define NEW_SHAPEVEC(_name, _type, _value) \
00036 vector<Shape<_type> > _name((_value));
00037
00038
00039 #define NEW_SHAPEROOTVEC(_name, _value) \
00040 vector<ShapeRoot> _name((_value));
00041
00042
00043 #define SHAPEVEC_ITERATE(_shapesvec,_type,_var) \
00044 for ( std::vector<Shape<_type> >::iterator _var##_it = _shapesvec.begin(); \
00045 _var##_it != _shapesvec.end(); _var##_it++ ) { \
00046 Shape<_type> &_var = *_var##_it;
00047
00048
00049 #define SHAPENEXT_ITERATE(_shapesvec,_type,_var1,_var2) \
00050 for ( std::vector<Shape<_type> >::iterator _var2##_it = ++std::vector<Shape<_type> >::iterator(_var1##_it); \
00051 _var2##_it != _shapesvec.end(); _var2##_it++ ) { \
00052 Shape<_type> &_var2 = *_var2##_it;
00053
00054
00055 #define SHAPEROOTVEC_ITERATE(_shapesvec,_var) \
00056 for ( std::vector<ShapeRoot>::iterator _var##_it = _shapesvec.begin(); \
00057 _var##_it != _shapesvec.end(); _var##_it++ ) { \
00058 ShapeRoot &_var = *_var##_it;
00059
00060 #define END_ITERATE }
00061
00062
00063 #define DO_SHAPEVEC(_shapesvec,_type,_var,_body) \
00064 for ( std::vector<Shape<_type> >::iterator _var##_it = _shapesvec.begin(); \
00065 _var##_it != _shapesvec.end(); _var##_it++ ) { \
00066 Shape<_type> &_var = *_var##_it; \
00067 _body } \
00068
00069
00070 #define DO_SHAPENEXT(_shapesvec,_type,_var1,_var2,_body) \
00071 for ( std::vector<Shape<_type> >::iterator _var2##_it = ++std::vector<Shape<_type> >::iterator(_var1##_it); \
00072 _var2##_it != _shapesvec.end(); _var2##_it++ ) { \
00073 Shape<_type> &_var2 = *_var2##_it; \
00074 _body }
00075
00076
00077 #define DO_SHAPEROOTVEC(_shapesvec,_var,_body) \
00078 for ( std::vector<ShapeRoot>::iterator _var##_it = _shapesvec.begin(); \
00079 _var##_it != _shapesvec.end(); _var##_it++ ) { \
00080 ShapeRoot &_var = *_var##_it; \
00081 _body }
00082
00083
00084
00085
00086 class UnaryShapeRootPred : public unary_function<ShapeRoot, bool> {
00087 public:
00088 virtual ~UnaryShapeRootPred() {}
00089 };
00090
00091
00092 class BinaryShapeRootPred : public binary_function<ShapeRoot, ShapeRoot, bool> {
00093 public:
00094 virtual ~BinaryShapeRootPred() {}
00095 };
00096
00097
00098 template <class T>
00099 class UnaryShapePred : public unary_function<Shape<T>, bool> {
00100 public:
00101 virtual ~UnaryShapePred() {}
00102 };
00103
00104
00105 template <class T>
00106 class BinaryShapePred : public binary_function<Shape<T>, Shape<T>, bool> {
00107 public:
00108 virtual ~BinaryShapePred() {}
00109 };
00110
00111
00112
00113
00114
00115 template<typename PredType1, typename PredType2>
00116 class shortcircuit_and : public unary_function<typename PredType1::argument_type,bool> {
00117 public:
00118 PredType1 p1;
00119 PredType2 p2;
00120 shortcircuit_and(PredType1 _p1, PredType2 _p2) :
00121 unary_function<typename PredType1::argument_type,bool>(), p1(_p1), p2(_p2) {}
00122 bool operator() (const typename PredType1::argument_type &shape) const {
00123 if ( p1(shape) )
00124 return p2(shape);
00125 else return false;
00126 }
00127 };
00128
00129 template<typename PredType1, typename PredType2>
00130 class shortcircuit_or : public unary_function<typename PredType1::argument_type,bool> {
00131 public:
00132 PredType1 p1;
00133 PredType2 p2;
00134 shortcircuit_or(PredType1 _p1, PredType2 _p2) :
00135 unary_function<typename PredType1::argument_type,bool>(), p1(_p1), p2(_p2) {}
00136 bool operator() (const typename PredType1::argument_type &shape) const {
00137 if ( p1(shape) )
00138 return true;
00139 else return p2(shape);
00140 }
00141 };
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 template<typename PredType1, typename PredType2>
00155 shortcircuit_and<PredType1,PredType2> andPred(PredType1 p1, PredType2 p2) {
00156 return shortcircuit_and<PredType1,PredType2>(p1,p2);
00157 }
00158
00159
00160 template<typename PredType1, typename PredType2>
00161 shortcircuit_or<PredType1,PredType2> orPred(PredType1 p1, PredType2 p2) {
00162 return shortcircuit_or<PredType1,PredType2>(p1,p2);
00163 }
00164
00165
00166
00167
00168
00169 class isType : public UnaryShapeRootPred {
00170 public:
00171 ShapeType_t type;
00172 explicit isType(ShapeType_t _type) : UnaryShapeRootPred(), type(_type) {}
00173 bool operator()(const ShapeRoot &shape) const {
00174 return shape->getType() == type; }
00175 };
00176
00177 class isColor : public UnaryShapeRootPred {
00178 public:
00179 rgb color;
00180 explicit isColor(int colorIndex) : UnaryShapeRootPred(), color(ProjectInterface::getColorRGB(colorIndex)) {}
00181 explicit isColor(rgb _color) : UnaryShapeRootPred(), color(_color) {}
00182 explicit isColor(std::string const &_colorname) : UnaryShapeRootPred(), color(ProjectInterface::getColorRGB(_colorname)) {}
00183 bool operator()(const ShapeRoot &shape) const {
00184 return shape->getColor() == color; }
00185 };
00186
00187 class isName : public UnaryShapeRootPred {
00188 public:
00189 std::string name;
00190 explicit isName(std::string _name) : UnaryShapeRootPred(), name(_name) {}
00191 bool operator()(const ShapeRoot &shape) const {
00192
00193 return shape->getName() == name; }
00194 };
00195
00196
00197
00198 template<class T, typename PredType>
00199 Shape<T> find_if(const vector<Shape<T> > &vec, PredType pred) {
00200 typename vector<Shape<T> >::const_iterator result = find_if(vec.begin(),vec.end(),pred);
00201 if ( result != vec.end() )
00202 return *result;
00203 else
00204 return Shape<T>();
00205 }
00206
00207
00208 template<class T>
00209 Shape<T> find_shape(const vector<ShapeRoot> &vec, const std::string &name) {
00210 for ( vector<ShapeRoot>::const_iterator it = vec.begin();
00211 it != vec.end(); it++ )
00212 if ( (*it)->getType() == T::getStaticType() && (*it)->getName() == name )
00213 return ShapeRootTypeConst(*it,T);
00214 return Shape<T>();
00215 }
00216
00217
00218 template<class T>
00219 std::vector<Shape<T> > select_type(std::vector<ShapeRoot> &vec) {
00220 std::vector<Shape<T> > result(vec.size());
00221 result.clear();
00222 isType tpred(T::getStaticType());
00223 DO_SHAPEROOTVEC(vec, element, {
00224 if ( tpred(element) ) result.push_back(reinterpret_cast<const Shape<T>&>(element));
00225 });
00226 return result;
00227 }
00228
00229 template<class T, typename PredType>
00230 std::vector<Shape<T> > subset(const std::vector<Shape<T> > &vec, PredType pred) {
00231 std::vector<Shape<T> > result;
00232 remove_copy_if(vec.begin(), vec.end(),
00233 std::back_insert_iterator<std::vector<Shape<T> > >(result),
00234 not1(pred));
00235 return result;
00236 }
00237
00238 template<class T, typename ComparisonType>
00239 Shape<T> max_element(const vector<Shape<T> > &vec, ComparisonType comp) {
00240 typename vector<Shape<T> >::const_iterator result = max_element(vec.begin(),vec.end(),comp);
00241 if ( result != vec.end() )
00242 return *result;
00243 else
00244 return Shape<T>();
00245 }
00246
00247 template<class T, typename ComparisonType>
00248 Shape<T> min_element(const vector<Shape<T> > &vec, ComparisonType comp) {
00249 return max_element(vec, not2(comp));
00250 }
00251
00252
00253 template<class T, typename PredType>
00254 std::vector<Shape<T> > stable_sort(const std::vector<Shape<T> > &vec, PredType pred) {
00255 std::vector<Shape<T> > result(vec);
00256 stable_sort(result.begin(), result.end(), pred);
00257 return result;
00258 }
00259
00260
00261
00262
00263
00264
00265
00266 #define DIRECTION_PAIR(dir, oppdir) \
00267 class Is##dir : public BinaryShapeRootPred { \
00268 public: \
00269 Is##dir(float distance=0) : dist(distance) {} \
00270 bool operator() (const ShapeRoot&, const ShapeRoot&) const; \
00271 private: \
00272 float dist; \
00273 }; \
00274 \
00275 class Is##dir##This : public UnaryShapeRootPred { \
00276 public: \
00277 Is##dir##This(const ShapeRoot &_s2, float distance=0) : \
00278 UnaryShapeRootPred(), s2(_s2), dist(distance) {} \
00279 bool operator() (const ShapeRoot &s1) const { \
00280 return Is##dir(dist)(s1,s2); } \
00281 private: \
00282 ShapeRoot s2; \
00283 float dist; \
00284 }; \
00285 \
00286 class Is##oppdir : public BinaryShapeRootPred { \
00287 public: \
00288 Is##oppdir(float distance=0) : dist(distance) {} \
00289 bool operator() (const ShapeRoot &s1, const ShapeRoot &s2) const { \
00290 return Is##dir(dist) (s2, s1); } \
00291 private: \
00292 float dist; \
00293 }; \
00294 \
00295 class Is##oppdir##This : public UnaryShapeRootPred { \
00296 public: \
00297 Is##oppdir##This(const ShapeRoot &_s2, float distance=0) : \
00298 UnaryShapeRootPred(), s2(_s2), dist(distance) {} \
00299 bool operator() (const ShapeRoot &s1) const { \
00300 return Is##dir(dist) (s2,s1); } \
00301 private: \
00302 ShapeRoot s2; \
00303 float dist; \
00304 };
00305
00306
00307 DIRECTION_PAIR(LeftOf, RightOf)
00308 DIRECTION_PAIR(Above, Below)
00309
00310 #undef DIRECTION_PAIR
00311
00312 }
00313
00314 #endif