1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 // Tool reporting Implementation Status in QBK format
4 // Copyright (c) 2011-2014 Barend Gehrels, Amsterdam, the Netherlands.
5 // Copyright (c) 2011-2014 Bruno Lalande, Paris, France.
7 // Use, modification and distribution is subject to the Boost Software License,
8 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
19 #include <boost/timer.hpp>
20 #include <boost/algorithm/string/predicate.hpp>
21 #include <boost/algorithm/string/replace.hpp>
22 #include <boost/algorithm/string/trim.hpp>
24 static const int point
= 0;
25 static const int segment
= 1;
26 static const int box
= 2;
27 static const int linestring
= 3;
28 static const int ring
= 4;
29 static const int polygon
= 5;
30 static const int multi_point
= 6;
31 static const int multi_linestring
= 7;
32 static const int multi_polygon
= 8;
33 static const int variant
= 9;
34 static const int geometry_count
= 10;
38 static inline bool apply(std::string
const& id
)
40 std::ostringstream command
;
42 command
<< "b2 -a tmp > tmp/t_" << id
<< ".out";
43 //command << "b2 -a tmp > tmp/t.out";
44 int failed
= system(command
.str().c_str());
47 // For debugging: save t.cpp
48 std::ostringstream c2
;
49 c2
<< "cp tmp/t.cpp tmp/t_" << id
<< ".cpp";
50 system(c2
.str().c_str());
65 inline bool apply(std::string
const& id
)
69 // Generate the pre-compiled header
70 system("clang -x c++-header -I . -I ../../../../../../.. implementation_status.hpp");
74 std::ostringstream command
;
75 // We compile only, not even link
76 command
<< "clang -include implementation_status.hpp -I . -I ../../../../../../.. -c tmp/t.cpp > tmp/t_" << id
<< ".out 2>&1";
77 int failed
= system(command
.str().c_str());
80 // For debugging: save t.cpp
81 std::ostringstream c2
;
82 c2
<< "cp tmp/t.cpp tmp/t_" << id
<< ".cpp";
83 system(c2
.str().c_str());
99 inline bool apply(std::string
const& id
)
101 std::ostringstream command
;
102 command
<< "cl /nologo -I. -I/_svn/boost/trunk /EHsc /Y";
105 std::cout
<< " (creating PCH)";
114 command
<< "implementation_status.hpp tmp/t.cpp > tmp/t" //.out";
118 int failed
= system(command
.str().c_str());
128 explicit algorithm(std::string
const& n
, int a
= 1)
135 inline std::string
bool_string(bool v
)
137 return v
? "true" : "false";
140 inline std::string
typedef_string(int type
, bool clockwise
, bool open
)
142 std::ostringstream out
;
145 case point
: return "P";
146 case linestring
: return "bg::model::linestring<P>";
147 case box
: return "bg::model::box<P>";
148 case segment
: return "bg::model::segment<P>";
150 out
<< "bg::model::ring<P, "
151 << bool_string(clockwise
) << ", " << bool_string(open
) << ">";
155 out
<< "bg::model::polygon<P, "
156 << bool_string(clockwise
) << ", " << bool_string(open
) << ">";
158 case multi_point
: return "bg::model::multi_point<P>";
159 case multi_linestring
:
160 out
<< "bg::model::multi_linestring<bg::model::linestring<P> >";
163 out
<< "bg::model::multi_polygon<bg::model::polygon<P, "
164 << bool_string(clockwise
) << ", " << bool_string(open
) << "> >";
170 inline std::string
wkt_string(int type
)
174 case point
: return "POINT(1 1)";
175 case linestring
: return "LINESTRING(1 1,2 2)";
176 case segment
: return "LINESTRING(1 1,2 2)";
177 case box
: return "POLYGON((1 1,2 2))";
181 return "POLYGON((0 0,0 1,1 1,0 0))";
182 case multi_point
: return "MULTIPOINT((1 1),(2 2))";
183 case multi_linestring
: return "MULTILINESTRING((1 1,2 2))";
184 case multi_polygon
: return "MULTIPOLYGON(((0 0,0 1,1 1,0 0)))";
189 inline std::string
geometry_string(int type
)
193 case point
: return "Point";
194 case linestring
: return "Linestring";
195 case box
: return "Box";
196 case polygon
: return "Polygon";
197 case ring
: return "Ring";
198 case segment
: return "Segment";
199 case multi_point
: return "MultiPoint";
200 case multi_linestring
: return "MultiLinestring";
201 case multi_polygon
: return "MultiPolygon";
202 case variant
: return "Variant";
207 template <typename CompilePolicy
>
208 int report_library(CompilePolicy
& compile_policy
,
209 int type
, algorithm
const& algo
, bool clockwise
,
210 bool open
, int dimensions
, std::string
const& cs
,
215 std::ostringstream out
;
216 out
<< geometry_string(type
);
219 out
<< "_" << geometry_string(type2
);
223 << "_" << bool_string(clockwise
)
224 << "_" << bool_string(open
)
225 << "_" << boost::replace_all_copy
227 boost::replace_all_copy
229 boost::replace_all_copy(cs
, "bg::", "")
240 std::ofstream
out("tmp/t.cpp");
242 std::string name
= "geometry";
249 out
<< "#include <implementation_status.hpp>" << std::endl
;
253 out
<< "#include <boost/variant/variant.hpp>" << std::endl
;
257 << "template <typename P>" << std::endl
258 << "inline void test()" << std::endl
260 << " namespace bg = boost::geometry;" << std::endl
261 << " " << typedef_string(type
, clockwise
, open
) << " " << name
<< ";" << std::endl
262 << " bg::read_wkt(\"" << wkt_string(type
) << "\", " << name
<< ");" << std::endl
;
267 << " typedef " << typedef_string(polygon
, clockwise
, open
) << " type1;" << std::endl
268 << " typedef " << typedef_string(box
, clockwise
, open
) << " type2;" << std::endl
269 << " boost::variant<type1, type2> geometry;" << std::endl
270 << " geometry = source;"
277 << " " << typedef_string(type2
, clockwise
, open
) << " geometry2;" << std::endl
278 << " bg::read_wkt(\"" << wkt_string(type2
) << "\", geometry2);" << std::endl
;
281 if (algo
.name
== std::string("centroid"))
284 out
<< " bg::" << algo
.name
<< "(geometry, point);" << std::endl
;
286 else if (algo
.name
== std::string("envelope"))
288 out
<< " bg::model::box<P> box;";
289 out
<< " bg::" << algo
.name
<< "(geometry, box);" << std::endl
;
296 out
<< " bg::" << algo
.name
<< "(geometry);" << std::endl
;
299 // For cases as point-in-polygon, take first geometry 2 (point), then geometry (polygon) such that
300 // it is listed as column:point in row:polygon
301 out
<< " bg::" << algo
.name
<< "(geometry2, geometry);" << std::endl
;
312 << "int main()" << std::endl
314 << " namespace bg = boost::geometry;" << std::endl
315 << " test<bg::model::point< double, " << dimensions
<< ", bg::cs::" << cs
<< " > >();" << std::endl
316 << " return 0;" << std::endl
322 bool result
= compile_policy
.apply(lit
);
325 std::cout
<< " ERROR";
327 std::cout
<< std::endl
;
332 template <typename CompilePolicy
>
333 std::vector
<int> report(CompilePolicy
& compile_policy
,
334 int type
, algorithm
const& algo
, bool clockwise
,
335 bool open
, int dimensions
, std::string
const& cs
)
337 std::vector
<int> result
;
342 result
.push_back(report_library(compile_policy
, type
, algo
, clockwise
, open
, dimensions
, cs
));
345 for (int type2
= point
; type2
< geometry_count
; ++type2
)
347 result
.push_back(report_library(compile_policy
, type
, algo
, clockwise
, open
, dimensions
, cs
, type2
));
360 cs(std::string
const& n
)
366 int main(int , char** )
368 #if defined(_MSC_VER)
369 compile_msvc compile_policy
;
371 //compile_bjam compile_policy;
372 compile_clang compile_policy
;
375 typedef std::vector
<algorithm
> v_a_type
;
377 algorithms
.push_back(algorithm("area"));
378 algorithms
.push_back(algorithm("clear"));
379 algorithms
.push_back(algorithm("correct"));
380 algorithms
.push_back(algorithm("centroid")); // NOTE: current doc contains 2D / 3D
381 algorithms
.push_back(algorithm("envelope"));
382 algorithms
.push_back(algorithm("length"));
383 algorithms
.push_back(algorithm("is_simple"));
384 algorithms
.push_back(algorithm("is_valid"));
385 algorithms
.push_back(algorithm("num_points"));
386 algorithms
.push_back(algorithm("perimeter"));
388 algorithms
.push_back(algorithm("covered_by", 2));
389 algorithms
.push_back(algorithm("distance", 2));
390 algorithms
.push_back(algorithm("crosses", 2));
391 algorithms
.push_back(algorithm("disjoint", 2));
392 algorithms
.push_back(algorithm("equals", 2));
393 algorithms
.push_back(algorithm("intersects", 2));
394 algorithms
.push_back(algorithm("overlaps", 2));
395 algorithms
.push_back(algorithm("within", 2));
397 typedef std::vector
<cs
> cs_type
;
399 css
.push_back(cs("cartesian"));
400 // css.push_back(cs("spherical<bg::degree>"));
401 // css.push_back(cs("spherical<bg::radian>"));
406 for (v_a_type::const_iterator it
= algorithms
.begin(); it
!= algorithms
.end(); ++it
)
408 /*([heading Behavior]
411 [[__2dim__][All combinations of: box, ring, polygon, multi_polygon]]
412 [[__other__][__nyiversion__]]
413 [[__sph__][__nyiversion__]]
414 [[Three dimensional][__nyiversion__]]
417 std::ostringstream name
;
418 name
<< "../../../../reference/status/" << it
->name
<< "_status.qbk";
420 std::ofstream
out(name
.str().c_str());
421 out
<< "[heading Supported geometries]" << std::endl
;
423 cs_type::const_iterator cit
= css
.begin();
426 // Construct the table
428 std::vector
<std::vector
<int> > table
;
430 for (int type
= point
; type
< geometry_count
; type
++)
432 table
.push_back(report(compile_policy
, type
, *it
, true, true, 2, cit
->name
));
437 // Detect red rows/columns
439 std::vector
<int> lines_status(table
.size(), false);
440 std::vector
<int> columns_status(table
[0].size(), false);
442 for (unsigned int i
= 0; i
!= table
.size(); ++i
)
444 for (unsigned int j
= 0; j
!= table
[i
].size(); ++j
)
446 lines_status
[i
] |= table
[i
][j
];
447 columns_status
[j
] |= table
[i
][j
];
455 out
<< "[table" << std::endl
<< "[";
460 for (int type
= point
; type
< geometry_count
; type
++)
463 if (!columns_status
[type
]) continue;
465 out
<< "[" << geometry_string(type
) << "]";
470 out
<< "[Geometry][Status]";
473 out
<< "]" << std::endl
;
475 for (unsigned int i
= 0; i
!= table
.size(); ++i
)
478 if (!lines_status
[i
]) continue;
481 out
<< "[" << geometry_string(i
) << "]";
482 for (unsigned int j
= 0; j
!= table
[i
].size(); ++j
)
485 if (!columns_status
[j
]) continue;
487 out
<< "[ [$img/" << (table
[i
][j
] ? "ok" : "nyi") << ".png] ]";
489 out
<< "]" << std::endl
;
492 out
<< "]" << std::endl
;
496 std::cout
<< "TIME: " << timer
.elapsed() << std::endl
;