string_cast.inl 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. /// @ref gtx_string_cast
  2. #include <cstdarg>
  3. #include <cstdio>
  4. namespace glm{
  5. namespace detail
  6. {
  7. template <typename T>
  8. struct cast
  9. {
  10. typedef T value_type;
  11. };
  12. template <>
  13. struct cast<float>
  14. {
  15. typedef double value_type;
  16. };
  17. GLM_FUNC_QUALIFIER std::string format(const char* msg, ...)
  18. {
  19. std::size_t const STRING_BUFFER(4096);
  20. char text[STRING_BUFFER];
  21. va_list list;
  22. if(msg == GLM_NULLPTR)
  23. return std::string();
  24. va_start(list, msg);
  25. # if (GLM_COMPILER & GLM_COMPILER_VC)
  26. vsprintf_s(text, STRING_BUFFER, msg, list);
  27. # else//
  28. std::vsprintf(text, msg, list);
  29. # endif//
  30. va_end(list);
  31. return std::string(text);
  32. }
  33. static const char* LabelTrue = "true";
  34. static const char* LabelFalse = "false";
  35. template<typename T, bool isFloat = false>
  36. struct literal
  37. {
  38. GLM_FUNC_QUALIFIER static char const * value() {return "%d";}
  39. };
  40. template<typename T>
  41. struct literal<T, true>
  42. {
  43. GLM_FUNC_QUALIFIER static char const * value() {return "%f";}
  44. };
  45. # if GLM_MODEL == GLM_MODEL_32 && GLM_COMPILER && GLM_COMPILER_VC
  46. template<>
  47. struct literal<uint64_t, false>
  48. {
  49. GLM_FUNC_QUALIFIER static char const * value() {return "%lld";}
  50. };
  51. template<>
  52. struct literal<int64_t, false>
  53. {
  54. GLM_FUNC_QUALIFIER static char const * value() {return "%lld";}
  55. };
  56. # endif//GLM_MODEL == GLM_MODEL_32 && GLM_COMPILER && GLM_COMPILER_VC
  57. template<typename T>
  58. struct prefix{};
  59. template<>
  60. struct prefix<float>
  61. {
  62. GLM_FUNC_QUALIFIER static char const * value() {return "";}
  63. };
  64. template<>
  65. struct prefix<double>
  66. {
  67. GLM_FUNC_QUALIFIER static char const * value() {return "d";}
  68. };
  69. template<>
  70. struct prefix<bool>
  71. {
  72. GLM_FUNC_QUALIFIER static char const * value() {return "b";}
  73. };
  74. template<>
  75. struct prefix<uint8_t>
  76. {
  77. GLM_FUNC_QUALIFIER static char const * value() {return "u8";}
  78. };
  79. template<>
  80. struct prefix<int8_t>
  81. {
  82. GLM_FUNC_QUALIFIER static char const * value() {return "i8";}
  83. };
  84. template<>
  85. struct prefix<uint16_t>
  86. {
  87. GLM_FUNC_QUALIFIER static char const * value() {return "u16";}
  88. };
  89. template<>
  90. struct prefix<int16_t>
  91. {
  92. GLM_FUNC_QUALIFIER static char const * value() {return "i16";}
  93. };
  94. template<>
  95. struct prefix<uint32_t>
  96. {
  97. GLM_FUNC_QUALIFIER static char const * value() {return "u";}
  98. };
  99. template<>
  100. struct prefix<int32_t>
  101. {
  102. GLM_FUNC_QUALIFIER static char const * value() {return "i";}
  103. };
  104. template<>
  105. struct prefix<uint64_t>
  106. {
  107. GLM_FUNC_QUALIFIER static char const * value() {return "u64";}
  108. };
  109. template<>
  110. struct prefix<int64_t>
  111. {
  112. GLM_FUNC_QUALIFIER static char const * value() {return "i64";}
  113. };
  114. template<typename matType>
  115. struct compute_to_string
  116. {};
  117. template<qualifier Q>
  118. struct compute_to_string<vec<1, bool, Q> >
  119. {
  120. GLM_FUNC_QUALIFIER static std::string call(vec<1, bool, Q> const& x)
  121. {
  122. return detail::format("bvec1(%s)",
  123. x[0] ? detail::LabelTrue : detail::LabelFalse);
  124. }
  125. };
  126. template<qualifier Q>
  127. struct compute_to_string<vec<2, bool, Q> >
  128. {
  129. GLM_FUNC_QUALIFIER static std::string call(vec<2, bool, Q> const& x)
  130. {
  131. return detail::format("bvec2(%s, %s)",
  132. x[0] ? detail::LabelTrue : detail::LabelFalse,
  133. x[1] ? detail::LabelTrue : detail::LabelFalse);
  134. }
  135. };
  136. template<qualifier Q>
  137. struct compute_to_string<vec<3, bool, Q> >
  138. {
  139. GLM_FUNC_QUALIFIER static std::string call(vec<3, bool, Q> const& x)
  140. {
  141. return detail::format("bvec3(%s, %s, %s)",
  142. x[0] ? detail::LabelTrue : detail::LabelFalse,
  143. x[1] ? detail::LabelTrue : detail::LabelFalse,
  144. x[2] ? detail::LabelTrue : detail::LabelFalse);
  145. }
  146. };
  147. template<qualifier Q>
  148. struct compute_to_string<vec<4, bool, Q> >
  149. {
  150. GLM_FUNC_QUALIFIER static std::string call(vec<4, bool, Q> const& x)
  151. {
  152. return detail::format("bvec4(%s, %s, %s, %s)",
  153. x[0] ? detail::LabelTrue : detail::LabelFalse,
  154. x[1] ? detail::LabelTrue : detail::LabelFalse,
  155. x[2] ? detail::LabelTrue : detail::LabelFalse,
  156. x[3] ? detail::LabelTrue : detail::LabelFalse);
  157. }
  158. };
  159. template<typename T, qualifier Q>
  160. struct compute_to_string<vec<1, T, Q> >
  161. {
  162. GLM_FUNC_QUALIFIER static std::string call(vec<1, T, Q> const& x)
  163. {
  164. char const * PrefixStr = prefix<T>::value();
  165. char const * LiteralStr = literal<T, std::numeric_limits<T>::is_iec559>::value();
  166. std::string FormatStr(detail::format("%svec1(%s)",
  167. PrefixStr,
  168. LiteralStr));
  169. return detail::format(FormatStr.c_str(),
  170. static_cast<typename cast<T>::value_type>(x[0]));
  171. }
  172. };
  173. template<typename T, qualifier Q>
  174. struct compute_to_string<vec<2, T, Q> >
  175. {
  176. GLM_FUNC_QUALIFIER static std::string call(vec<2, T, Q> const& x)
  177. {
  178. char const * PrefixStr = prefix<T>::value();
  179. char const * LiteralStr = literal<T, std::numeric_limits<T>::is_iec559>::value();
  180. std::string FormatStr(detail::format("%svec2(%s, %s)",
  181. PrefixStr,
  182. LiteralStr, LiteralStr));
  183. return detail::format(FormatStr.c_str(),
  184. static_cast<typename cast<T>::value_type>(x[0]),
  185. static_cast<typename cast<T>::value_type>(x[1]));
  186. }
  187. };
  188. template<typename T, qualifier Q>
  189. struct compute_to_string<vec<3, T, Q> >
  190. {
  191. GLM_FUNC_QUALIFIER static std::string call(vec<3, T, Q> const& x)
  192. {
  193. char const * PrefixStr = prefix<T>::value();
  194. char const * LiteralStr = literal<T, std::numeric_limits<T>::is_iec559>::value();
  195. std::string FormatStr(detail::format("%svec3(%s, %s, %s)",
  196. PrefixStr,
  197. LiteralStr, LiteralStr, LiteralStr));
  198. return detail::format(FormatStr.c_str(),
  199. static_cast<typename cast<T>::value_type>(x[0]),
  200. static_cast<typename cast<T>::value_type>(x[1]),
  201. static_cast<typename cast<T>::value_type>(x[2]));
  202. }
  203. };
  204. template<typename T, qualifier Q>
  205. struct compute_to_string<vec<4, T, Q> >
  206. {
  207. GLM_FUNC_QUALIFIER static std::string call(vec<4, T, Q> const& x)
  208. {
  209. char const * PrefixStr = prefix<T>::value();
  210. char const * LiteralStr = literal<T, std::numeric_limits<T>::is_iec559>::value();
  211. std::string FormatStr(detail::format("%svec4(%s, %s, %s, %s)",
  212. PrefixStr,
  213. LiteralStr, LiteralStr, LiteralStr, LiteralStr));
  214. return detail::format(FormatStr.c_str(),
  215. static_cast<typename cast<T>::value_type>(x[0]),
  216. static_cast<typename cast<T>::value_type>(x[1]),
  217. static_cast<typename cast<T>::value_type>(x[2]),
  218. static_cast<typename cast<T>::value_type>(x[3]));
  219. }
  220. };
  221. template<typename T, qualifier Q>
  222. struct compute_to_string<mat<2, 2, T, Q> >
  223. {
  224. GLM_FUNC_QUALIFIER static std::string call(mat<2, 2, T, Q> const& x)
  225. {
  226. char const * PrefixStr = prefix<T>::value();
  227. char const * LiteralStr = literal<T, std::numeric_limits<T>::is_iec559>::value();
  228. std::string FormatStr(detail::format("%smat2x2((%s, %s), (%s, %s))",
  229. PrefixStr,
  230. LiteralStr, LiteralStr,
  231. LiteralStr, LiteralStr));
  232. return detail::format(FormatStr.c_str(),
  233. static_cast<typename cast<T>::value_type>(x[0][0]), static_cast<typename cast<T>::value_type>(x[0][1]),
  234. static_cast<typename cast<T>::value_type>(x[1][0]), static_cast<typename cast<T>::value_type>(x[1][1]));
  235. }
  236. };
  237. template<typename T, qualifier Q>
  238. struct compute_to_string<mat<2, 3, T, Q> >
  239. {
  240. GLM_FUNC_QUALIFIER static std::string call(mat<2, 3, T, Q> const& x)
  241. {
  242. char const * PrefixStr = prefix<T>::value();
  243. char const * LiteralStr = literal<T, std::numeric_limits<T>::is_iec559>::value();
  244. std::string FormatStr(detail::format("%smat2x3((%s, %s, %s), (%s, %s, %s))",
  245. PrefixStr,
  246. LiteralStr, LiteralStr, LiteralStr,
  247. LiteralStr, LiteralStr, LiteralStr));
  248. return detail::format(FormatStr.c_str(),
  249. static_cast<typename cast<T>::value_type>(x[0][0]), static_cast<typename cast<T>::value_type>(x[0][1]), static_cast<typename cast<T>::value_type>(x[0][2]),
  250. static_cast<typename cast<T>::value_type>(x[1][0]), static_cast<typename cast<T>::value_type>(x[1][1]), static_cast<typename cast<T>::value_type>(x[1][2]));
  251. }
  252. };
  253. template<typename T, qualifier Q>
  254. struct compute_to_string<mat<2, 4, T, Q> >
  255. {
  256. GLM_FUNC_QUALIFIER static std::string call(mat<2, 4, T, Q> const& x)
  257. {
  258. char const * PrefixStr = prefix<T>::value();
  259. char const * LiteralStr = literal<T, std::numeric_limits<T>::is_iec559>::value();
  260. std::string FormatStr(detail::format("%smat2x4((%s, %s, %s, %s), (%s, %s, %s, %s))",
  261. PrefixStr,
  262. LiteralStr, LiteralStr, LiteralStr, LiteralStr,
  263. LiteralStr, LiteralStr, LiteralStr, LiteralStr));
  264. return detail::format(FormatStr.c_str(),
  265. static_cast<typename cast<T>::value_type>(x[0][0]), static_cast<typename cast<T>::value_type>(x[0][1]), static_cast<typename cast<T>::value_type>(x[0][2]), static_cast<typename cast<T>::value_type>(x[0][3]),
  266. static_cast<typename cast<T>::value_type>(x[1][0]), static_cast<typename cast<T>::value_type>(x[1][1]), static_cast<typename cast<T>::value_type>(x[1][2]), static_cast<typename cast<T>::value_type>(x[1][3]));
  267. }
  268. };
  269. template<typename T, qualifier Q>
  270. struct compute_to_string<mat<3, 2, T, Q> >
  271. {
  272. GLM_FUNC_QUALIFIER static std::string call(mat<3, 2, T, Q> const& x)
  273. {
  274. char const * PrefixStr = prefix<T>::value();
  275. char const * LiteralStr = literal<T, std::numeric_limits<T>::is_iec559>::value();
  276. std::string FormatStr(detail::format("%smat3x2((%s, %s), (%s, %s), (%s, %s))",
  277. PrefixStr,
  278. LiteralStr, LiteralStr,
  279. LiteralStr, LiteralStr,
  280. LiteralStr, LiteralStr));
  281. return detail::format(FormatStr.c_str(),
  282. static_cast<typename cast<T>::value_type>(x[0][0]), static_cast<typename cast<T>::value_type>(x[0][1]),
  283. static_cast<typename cast<T>::value_type>(x[1][0]), static_cast<typename cast<T>::value_type>(x[1][1]),
  284. static_cast<typename cast<T>::value_type>(x[2][0]), static_cast<typename cast<T>::value_type>(x[2][1]));
  285. }
  286. };
  287. template<typename T, qualifier Q>
  288. struct compute_to_string<mat<3, 3, T, Q> >
  289. {
  290. GLM_FUNC_QUALIFIER static std::string call(mat<3, 3, T, Q> const& x)
  291. {
  292. char const * PrefixStr = prefix<T>::value();
  293. char const * LiteralStr = literal<T, std::numeric_limits<T>::is_iec559>::value();
  294. std::string FormatStr(detail::format("%smat3x3((%s, %s, %s), (%s, %s, %s), (%s, %s, %s))",
  295. PrefixStr,
  296. LiteralStr, LiteralStr, LiteralStr,
  297. LiteralStr, LiteralStr, LiteralStr,
  298. LiteralStr, LiteralStr, LiteralStr));
  299. return detail::format(FormatStr.c_str(),
  300. static_cast<typename cast<T>::value_type>(x[0][0]), static_cast<typename cast<T>::value_type>(x[0][1]), static_cast<typename cast<T>::value_type>(x[0][2]),
  301. static_cast<typename cast<T>::value_type>(x[1][0]), static_cast<typename cast<T>::value_type>(x[1][1]), static_cast<typename cast<T>::value_type>(x[1][2]),
  302. static_cast<typename cast<T>::value_type>(x[2][0]), static_cast<typename cast<T>::value_type>(x[2][1]), static_cast<typename cast<T>::value_type>(x[2][2]));
  303. }
  304. };
  305. template<typename T, qualifier Q>
  306. struct compute_to_string<mat<3, 4, T, Q> >
  307. {
  308. GLM_FUNC_QUALIFIER static std::string call(mat<3, 4, T, Q> const& x)
  309. {
  310. char const * PrefixStr = prefix<T>::value();
  311. char const * LiteralStr = literal<T, std::numeric_limits<T>::is_iec559>::value();
  312. std::string FormatStr(detail::format("%smat3x4((%s, %s, %s, %s), (%s, %s, %s, %s), (%s, %s, %s, %s))",
  313. PrefixStr,
  314. LiteralStr, LiteralStr, LiteralStr, LiteralStr,
  315. LiteralStr, LiteralStr, LiteralStr, LiteralStr,
  316. LiteralStr, LiteralStr, LiteralStr, LiteralStr));
  317. return detail::format(FormatStr.c_str(),
  318. static_cast<typename cast<T>::value_type>(x[0][0]), static_cast<typename cast<T>::value_type>(x[0][1]), static_cast<typename cast<T>::value_type>(x[0][2]), static_cast<typename cast<T>::value_type>(x[0][3]),
  319. static_cast<typename cast<T>::value_type>(x[1][0]), static_cast<typename cast<T>::value_type>(x[1][1]), static_cast<typename cast<T>::value_type>(x[1][2]), static_cast<typename cast<T>::value_type>(x[1][3]),
  320. static_cast<typename cast<T>::value_type>(x[2][0]), static_cast<typename cast<T>::value_type>(x[2][1]), static_cast<typename cast<T>::value_type>(x[2][2]), static_cast<typename cast<T>::value_type>(x[2][3]));
  321. }
  322. };
  323. template<typename T, qualifier Q>
  324. struct compute_to_string<mat<4, 2, T, Q> >
  325. {
  326. GLM_FUNC_QUALIFIER static std::string call(mat<4, 2, T, Q> const& x)
  327. {
  328. char const * PrefixStr = prefix<T>::value();
  329. char const * LiteralStr = literal<T, std::numeric_limits<T>::is_iec559>::value();
  330. std::string FormatStr(detail::format("%smat4x2((%s, %s), (%s, %s), (%s, %s), (%s, %s))",
  331. PrefixStr,
  332. LiteralStr, LiteralStr,
  333. LiteralStr, LiteralStr,
  334. LiteralStr, LiteralStr,
  335. LiteralStr, LiteralStr));
  336. return detail::format(FormatStr.c_str(),
  337. static_cast<typename cast<T>::value_type>(x[0][0]), static_cast<typename cast<T>::value_type>(x[0][1]),
  338. static_cast<typename cast<T>::value_type>(x[1][0]), static_cast<typename cast<T>::value_type>(x[1][1]),
  339. static_cast<typename cast<T>::value_type>(x[2][0]), static_cast<typename cast<T>::value_type>(x[2][1]),
  340. static_cast<typename cast<T>::value_type>(x[3][0]), static_cast<typename cast<T>::value_type>(x[3][1]));
  341. }
  342. };
  343. template<typename T, qualifier Q>
  344. struct compute_to_string<mat<4, 3, T, Q> >
  345. {
  346. GLM_FUNC_QUALIFIER static std::string call(mat<4, 3, T, Q> const& x)
  347. {
  348. char const * PrefixStr = prefix<T>::value();
  349. char const * LiteralStr = literal<T, std::numeric_limits<T>::is_iec559>::value();
  350. std::string FormatStr(detail::format("%smat4x3((%s, %s, %s), (%s, %s, %s), (%s, %s, %s), (%s, %s, %s))",
  351. PrefixStr,
  352. LiteralStr, LiteralStr, LiteralStr,
  353. LiteralStr, LiteralStr, LiteralStr,
  354. LiteralStr, LiteralStr, LiteralStr,
  355. LiteralStr, LiteralStr, LiteralStr));
  356. return detail::format(FormatStr.c_str(),
  357. static_cast<typename cast<T>::value_type>(x[0][0]), static_cast<typename cast<T>::value_type>(x[0][1]), static_cast<typename cast<T>::value_type>(x[0][2]),
  358. static_cast<typename cast<T>::value_type>(x[1][0]), static_cast<typename cast<T>::value_type>(x[1][1]), static_cast<typename cast<T>::value_type>(x[1][2]),
  359. static_cast<typename cast<T>::value_type>(x[2][0]), static_cast<typename cast<T>::value_type>(x[2][1]), static_cast<typename cast<T>::value_type>(x[2][2]),
  360. static_cast<typename cast<T>::value_type>(x[3][0]), static_cast<typename cast<T>::value_type>(x[3][1]), static_cast<typename cast<T>::value_type>(x[3][2]));
  361. }
  362. };
  363. template<typename T, qualifier Q>
  364. struct compute_to_string<mat<4, 4, T, Q> >
  365. {
  366. GLM_FUNC_QUALIFIER static std::string call(mat<4, 4, T, Q> const& x)
  367. {
  368. char const * PrefixStr = prefix<T>::value();
  369. char const * LiteralStr = literal<T, std::numeric_limits<T>::is_iec559>::value();
  370. std::string FormatStr(detail::format("%smat4x4((%s, %s, %s, %s), (%s, %s, %s, %s), (%s, %s, %s, %s), (%s, %s, %s, %s))",
  371. PrefixStr,
  372. LiteralStr, LiteralStr, LiteralStr, LiteralStr,
  373. LiteralStr, LiteralStr, LiteralStr, LiteralStr,
  374. LiteralStr, LiteralStr, LiteralStr, LiteralStr,
  375. LiteralStr, LiteralStr, LiteralStr, LiteralStr));
  376. return detail::format(FormatStr.c_str(),
  377. static_cast<typename cast<T>::value_type>(x[0][0]), static_cast<typename cast<T>::value_type>(x[0][1]), static_cast<typename cast<T>::value_type>(x[0][2]), static_cast<typename cast<T>::value_type>(x[0][3]),
  378. static_cast<typename cast<T>::value_type>(x[1][0]), static_cast<typename cast<T>::value_type>(x[1][1]), static_cast<typename cast<T>::value_type>(x[1][2]), static_cast<typename cast<T>::value_type>(x[1][3]),
  379. static_cast<typename cast<T>::value_type>(x[2][0]), static_cast<typename cast<T>::value_type>(x[2][1]), static_cast<typename cast<T>::value_type>(x[2][2]), static_cast<typename cast<T>::value_type>(x[2][3]),
  380. static_cast<typename cast<T>::value_type>(x[3][0]), static_cast<typename cast<T>::value_type>(x[3][1]), static_cast<typename cast<T>::value_type>(x[3][2]), static_cast<typename cast<T>::value_type>(x[3][3]));
  381. }
  382. };
  383. template<typename T, qualifier Q>
  384. struct compute_to_string<qua<T, Q> >
  385. {
  386. GLM_FUNC_QUALIFIER static std::string call(qua<T, Q> const& q)
  387. {
  388. char const * PrefixStr = prefix<T>::value();
  389. char const * LiteralStr = literal<T, std::numeric_limits<T>::is_iec559>::value();
  390. std::string FormatStr(detail::format("%squat(%s, {%s, %s, %s})",
  391. PrefixStr,
  392. LiteralStr, LiteralStr, LiteralStr, LiteralStr));
  393. return detail::format(FormatStr.c_str(),
  394. static_cast<typename cast<T>::value_type>(q.w),
  395. static_cast<typename cast<T>::value_type>(q.x),
  396. static_cast<typename cast<T>::value_type>(q.y),
  397. static_cast<typename cast<T>::value_type>(q.z));
  398. }
  399. };
  400. template<typename T, qualifier Q>
  401. struct compute_to_string<tdualquat<T, Q> >
  402. {
  403. GLM_FUNC_QUALIFIER static std::string call(tdualquat<T, Q> const& x)
  404. {
  405. char const * PrefixStr = prefix<T>::value();
  406. char const * LiteralStr = literal<T, std::numeric_limits<T>::is_iec559>::value();
  407. std::string FormatStr(detail::format("%sdualquat((%s, {%s, %s, %s}), (%s, {%s, %s, %s}))",
  408. PrefixStr,
  409. LiteralStr, LiteralStr, LiteralStr, LiteralStr,
  410. LiteralStr, LiteralStr, LiteralStr, LiteralStr));
  411. return detail::format(FormatStr.c_str(),
  412. static_cast<typename cast<T>::value_type>(x.real.w),
  413. static_cast<typename cast<T>::value_type>(x.real.x),
  414. static_cast<typename cast<T>::value_type>(x.real.y),
  415. static_cast<typename cast<T>::value_type>(x.real.z),
  416. static_cast<typename cast<T>::value_type>(x.dual.w),
  417. static_cast<typename cast<T>::value_type>(x.dual.x),
  418. static_cast<typename cast<T>::value_type>(x.dual.y),
  419. static_cast<typename cast<T>::value_type>(x.dual.z));
  420. }
  421. };
  422. }//namespace detail
  423. template<class matType>
  424. GLM_FUNC_QUALIFIER std::string to_string(matType const& x)
  425. {
  426. return detail::compute_to_string<matType>::call(x);
  427. }
  428. }//namespace glm