/Src/Dependencies/Boost/libs/geometry/doc/src/docutils/tools/implementation_status/implementation_status.cpp

http://hadesmem.googlecode.com/ · C++ · 402 lines · 314 code · 65 blank · 23 comment · 29 complexity · f3212849103b05cbb6e54bec46f2f4b6 MD5 · raw file

  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Tool reporting Implementation Status in QBK format
  3. // Copyright (c) 2011 Barend Gehrels, Amsterdam, the Netherlands.
  4. // Copyright (c) 2011 Bruno Lalande, Paris, France.
  5. // Use, modification and distribution is subject to the Boost Software License,
  6. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. #include <iostream>
  9. #include <fstream>
  10. #include <sstream>
  11. #include <string>
  12. #include <vector>
  13. #include <stdlib.h>
  14. #include <boost/timer.hpp>
  15. #include <boost/algorithm/string/predicate.hpp>
  16. #include <boost/algorithm/string/replace.hpp>
  17. #include <boost/algorithm/string/trim.hpp>
  18. static const int point = 0;
  19. static const int segment = 1;
  20. static const int box = 2;
  21. static const int linestring = 3;
  22. static const int ring = 4;
  23. static const int polygon = 5;
  24. static const int multi_point = 6;
  25. static const int multi_linestring = 7;
  26. static const int multi_polygon = 8;
  27. static const int geometry_count = 9;
  28. struct compile_bjam
  29. {
  30. static inline bool apply(int type1, int type2)
  31. {
  32. std::ostringstream command;
  33. // For debugging:
  34. command << "bjam -a tmp > tmp/t" << type1 << "_" << type2 << ".out";
  35. //command << "bjam -a tmp > tmp/t.out";
  36. int failed = system(command.str().c_str());
  37. return failed == 0;
  38. }
  39. };
  40. struct compile_msvc
  41. {
  42. bool first;
  43. int count;
  44. compile_msvc()
  45. : first(true)
  46. , count(0)
  47. {}
  48. inline bool apply(int type1, int type2)
  49. {
  50. std::ostringstream command;
  51. command << "cl /nologo -I. -I/_svn/boost/trunk /EHsc /Y";
  52. if (first)
  53. {
  54. std::cout << " (creating PCH)";
  55. command << "c";
  56. first = false;
  57. }
  58. else
  59. {
  60. command << "u";
  61. }
  62. command << "implementation_status.hpp tmp/t.cpp > tmp/t" //.out";
  63. // For debugging:
  64. << type1 << "_" << type2 << ".out";
  65. int failed = system(command.str().c_str());
  66. return failed == 0;
  67. }
  68. };
  69. struct algorithm
  70. {
  71. std::string name;
  72. int arity;
  73. explicit algorithm(std::string const& n, int a = 1)
  74. : name(n)
  75. , arity(a)
  76. {}
  77. };
  78. inline std::string bool_string(bool v)
  79. {
  80. return v ? "true" : "false";
  81. }
  82. inline std::string typedef_string(int type, bool clockwise, bool open)
  83. {
  84. std::ostringstream out;
  85. switch(type)
  86. {
  87. case point : return "P";
  88. case linestring : return "bg::model::linestring<P>";
  89. case box : return "bg::model::box<P>";
  90. case segment : return "bg::model::segment<P>";
  91. case ring :
  92. out << "bg::model::ring<P, "
  93. << bool_string(clockwise) << ", " << bool_string(open) << ">";
  94. break;
  95. case polygon :
  96. out << "bg::model::polygon<P, "
  97. << bool_string(clockwise) << ", " << bool_string(open) << ">";
  98. break;
  99. case multi_point : return "bg::model::multi_point<P>";
  100. case multi_linestring :
  101. out << "bg::model::multi_linestring<bg::model::linestring<P> >";
  102. break;
  103. case multi_polygon :
  104. out << "bg::model::multi_polygon<bg::model::polygon<P, "
  105. << bool_string(clockwise) << ", " << bool_string(open) << "> >";
  106. break;
  107. }
  108. return out.str();
  109. }
  110. inline std::string wkt_string(int type)
  111. {
  112. switch(type)
  113. {
  114. case point : return "POINT(1 1)";
  115. case linestring : return "LINESTRING(1 1,2 2)";
  116. case segment : return "LINESTRING(1 1,2 2)";
  117. case box : return "POLYGON((1 1,2 2)";
  118. case polygon :
  119. case ring :
  120. return "POLYGON((0 0,0 1,1 1,0 0))";
  121. case multi_point : return "MULTIPOINT((1 1),(2 2))";
  122. case multi_linestring : return "MULTILINESTRING((1 1,2 2))";
  123. case multi_polygon : return "MULTIPOLYGON(((0 0,0 1,1 1,0 0)))";
  124. }
  125. return "";
  126. }
  127. inline std::string geometry_string(int type)
  128. {
  129. switch(type)
  130. {
  131. case point : return "Point";
  132. case linestring : return "Linestring";
  133. case box : return "Box";
  134. case polygon : return "Polygon";
  135. case ring : return "Ring";
  136. case segment : return "Segment";
  137. case multi_point : return "MultiPoint";
  138. case multi_linestring : return "MultiLinestring";
  139. case multi_polygon : return "MultiPolygon";
  140. }
  141. return "";
  142. }
  143. template <typename CompilePolicy>
  144. int report_library(CompilePolicy& compile_policy,
  145. int type, algorithm const& algo, bool clockwise,
  146. bool open, int dimensions, std::string const& cs,
  147. int type2 = -1)
  148. {
  149. std::string lit;
  150. {
  151. std::ostringstream out;
  152. out << geometry_string(type);
  153. if (type2 != -1)
  154. {
  155. out << "_" << geometry_string(type2);
  156. }
  157. out
  158. << "_" << algo.name
  159. << "_" << bool_string(clockwise)
  160. << "_" << bool_string(open)
  161. << "_" << boost::replace_all_copy
  162. (
  163. boost::replace_all_copy
  164. (
  165. boost::replace_all_copy(cs, "bg::", "")
  166. , "<", "_"
  167. )
  168. , ">", "_"
  169. );
  170. lit = out.str();
  171. }
  172. std::cout << lit;
  173. {
  174. std::ofstream out("tmp/t.cpp");
  175. out
  176. << "#include <implementation_status.hpp>" << std::endl
  177. << "template <typename P>" << std::endl
  178. << "inline void test()" << std::endl
  179. << "{" << std::endl
  180. << " namespace bg = boost::geometry;" << std::endl
  181. << " " << typedef_string(type, clockwise, open) << " geometry;" << std::endl
  182. << " bg::read_wkt(\"" << wkt_string(type) << "\", geometry);" << std::endl;
  183. if (algo.arity > 1)
  184. {
  185. out
  186. << " " << typedef_string(type2, clockwise, open) << " geometry2;" << std::endl
  187. << " bg::read_wkt(\"" << wkt_string(type2) << "\", geometry2);" << std::endl;
  188. }
  189. switch(algo.arity)
  190. {
  191. case 1 :
  192. out << " bg::" << algo.name << "(geometry);" << std::endl;
  193. break;
  194. case 2 :
  195. out << " bg::" << algo.name << "(geometry, geometry2);" << std::endl;
  196. break;
  197. }
  198. out
  199. << "}" << std::endl
  200. << std::endl
  201. ;
  202. out
  203. << "int main()" << std::endl
  204. << "{" << std::endl
  205. << " namespace bg = boost::geometry;" << std::endl
  206. << " test<bg::model::point< double, " << dimensions << ", bg::cs::" << cs << " > >();" << std::endl
  207. << " return 0;" << std::endl
  208. << "}" << std::endl
  209. << std::endl
  210. ;
  211. }
  212. bool result = compile_policy.apply(type, type2);
  213. if (! result)
  214. {
  215. std::cout << " ERROR";
  216. }
  217. std::cout << std::endl;
  218. return result;
  219. }
  220. template <typename CompilePolicy>
  221. std::vector<int> report(CompilePolicy& compile_policy,
  222. int type, algorithm const& algo, bool clockwise,
  223. bool open, int dimensions, std::string const& cs)
  224. {
  225. std::vector<int> result;
  226. switch(algo.arity)
  227. {
  228. case 1 :
  229. result.push_back(report_library(compile_policy, type, algo, clockwise, open, dimensions, cs));
  230. break;
  231. case 2 :
  232. for (int type2 = point; type2 < geometry_count; ++type2)
  233. {
  234. result.push_back(report_library(compile_policy, type, algo, clockwise, open, dimensions, cs, type2));
  235. }
  236. break;
  237. }
  238. return result;
  239. }
  240. struct cs
  241. {
  242. std::string name;
  243. cs(std::string const& n)
  244. : name(n)
  245. {}
  246. };
  247. int main(int argc, char** argv)
  248. {
  249. #if defined(_MSC_VER)
  250. compile_msvc compile_policy;
  251. #else
  252. compile_bjam compile_policy;
  253. #endif
  254. typedef std::vector<algorithm> v_a_type;
  255. v_a_type algorithms;
  256. algorithms.push_back(algorithm("area"));
  257. algorithms.push_back(algorithm("length"));
  258. algorithms.push_back(algorithm("perimeter"));
  259. algorithms.push_back(algorithm("correct"));
  260. algorithms.push_back(algorithm("distance", 2));
  261. algorithms.push_back(algorithm("centroid", 2));
  262. algorithms.push_back(algorithm("intersects", 2));
  263. algorithms.push_back(algorithm("within", 2));
  264. algorithms.push_back(algorithm("equals", 2));
  265. typedef std::vector<cs> cs_type;
  266. cs_type css;
  267. css.push_back(cs("cartesian"));
  268. // css.push_back(cs("spherical<bg::degree>"));
  269. // css.push_back(cs("spherical<bg::radian>"));
  270. boost::timer timer;
  271. for (v_a_type::const_iterator it = algorithms.begin(); it != algorithms.end(); ++it)
  272. {
  273. /*([heading Behavior]
  274. [table
  275. [[Case] [Behavior] ]
  276. [[__2dim__][All combinations of: box, ring, polygon, multi_polygon]]
  277. [[__other__][__nyiversion__]]
  278. [[__sph__][__nyiversion__]]
  279. [[Three dimensional][__nyiversion__]]
  280. ]*/
  281. std::ostringstream name;
  282. name << "../../../../generated/" << it->name << "_status.qbk";
  283. std::ofstream out(name.str().c_str());
  284. out << "[heading Supported geometries]" << std::endl;
  285. cs_type::const_iterator cit = css.begin();
  286. {
  287. // Construct the table
  288. std::vector<std::vector<int> > table;
  289. for (int type = point; type < geometry_count; type++)
  290. {
  291. table.push_back(report(compile_policy, type, *it, true, true, 2, cit->name));
  292. }
  293. // Detect red rows/columns
  294. std::vector<int> lines_status(table.size(), false);
  295. std::vector<int> columns_status(table[0].size(), false);
  296. for (unsigned int i = 0; i != table.size(); ++i)
  297. {
  298. for (unsigned int j = 0; j != table[i].size(); ++j)
  299. {
  300. lines_status[i] |= table[i][j];
  301. columns_status[j] |= table[i][j];
  302. }
  303. }
  304. // Display the table
  305. out << "[table" << std::endl << "[";
  306. if (it->arity > 1)
  307. {
  308. out << "[ ]";
  309. for (int type = point; type < geometry_count; type++)
  310. {
  311. if (!columns_status[type]) continue;
  312. out << "[" << geometry_string(type) << "]";
  313. }
  314. }
  315. else
  316. {
  317. out << "[Geometry][Status]";
  318. }
  319. out << "]" << std::endl;
  320. for (unsigned int i = 0; i != table.size(); ++i)
  321. {
  322. if (!lines_status[i]) continue;
  323. out << "[";
  324. out << "[" << geometry_string(i) << "]";
  325. for (unsigned int j = 0; j != table[i].size(); ++j)
  326. {
  327. if (!columns_status[j]) continue;
  328. out << "[[$img/" << (table[i][j] ? "ok" : "nyi") << ".png]]";
  329. }
  330. out << "]" << std::endl;
  331. }
  332. out << "]" << std::endl;
  333. }
  334. }
  335. std::cout << "TIME: " << timer.elapsed() << std::endl;
  336. return 0;
  337. }