io.inl 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. /// @ref gtx_io
  2. /// @author Jan P Springer (regnirpsj@gmail.com)
  3. #include <iomanip> // std::fixed, std::setfill<>, std::setprecision, std::right, std::setw
  4. #include <ostream> // std::basic_ostream<>
  5. #include "../gtc/matrix_access.hpp" // glm::col, glm::row
  6. #include "../gtx/type_trait.hpp" // glm::type<>
  7. #if GLM_COMPILER & GLM_COMPILER_CLANG
  8. # pragma clang diagnostic push
  9. # pragma clang diagnostic ignored "-Wpadded"
  10. # pragma clang diagnostic ignored "-Wshorten-64-to-32"
  11. # pragma clang diagnostic ignored "-Wglobal-constructors"
  12. #endif
  13. namespace glm{
  14. namespace io
  15. {
  16. template<typename CTy>
  17. GLM_FUNC_QUALIFIER format_punct<CTy>::format_punct(size_t a)
  18. : std::locale::facet(a)
  19. , formatted(true)
  20. , precision(3)
  21. , width(1 + 4 + 1 + precision)
  22. , separator(',')
  23. , delim_left('[')
  24. , delim_right(']')
  25. , space(' ')
  26. , newline('\n')
  27. , order(column_major)
  28. {}
  29. template<typename CTy>
  30. GLM_FUNC_QUALIFIER format_punct<CTy>::format_punct(format_punct const& a)
  31. : std::locale::facet(0)
  32. , formatted(a.formatted)
  33. , precision(a.precision)
  34. , width(a.width)
  35. , separator(a.separator)
  36. , delim_left(a.delim_left)
  37. , delim_right(a.delim_right)
  38. , space(a.space)
  39. , newline(a.newline)
  40. , order(a.order)
  41. {}
  42. template<typename CTy> std::locale::id format_punct<CTy>::id;
  43. template<typename CTy, typename CTr>
  44. GLM_FUNC_QUALIFIER basic_state_saver<CTy, CTr>::basic_state_saver(std::basic_ios<CTy, CTr>& a)
  45. : state_(a)
  46. , flags_(a.flags())
  47. , precision_(a.precision())
  48. , width_(a.width())
  49. , fill_(a.fill())
  50. , locale_(a.getloc())
  51. {}
  52. template<typename CTy, typename CTr>
  53. GLM_FUNC_QUALIFIER basic_state_saver<CTy, CTr>::~basic_state_saver()
  54. {
  55. state_.imbue(locale_);
  56. state_.fill(fill_);
  57. state_.width(width_);
  58. state_.precision(precision_);
  59. state_.flags(flags_);
  60. }
  61. template<typename CTy, typename CTr>
  62. GLM_FUNC_QUALIFIER basic_format_saver<CTy, CTr>::basic_format_saver(std::basic_ios<CTy, CTr>& a)
  63. : bss_(a)
  64. {
  65. a.imbue(std::locale(a.getloc(), new format_punct<CTy>(get_facet<format_punct<CTy> >(a))));
  66. }
  67. template<typename CTy, typename CTr>
  68. GLM_FUNC_QUALIFIER
  69. basic_format_saver<CTy, CTr>::~basic_format_saver()
  70. {}
  71. GLM_FUNC_QUALIFIER precision::precision(unsigned a)
  72. : value(a)
  73. {}
  74. GLM_FUNC_QUALIFIER width::width(unsigned a)
  75. : value(a)
  76. {}
  77. template<typename CTy>
  78. GLM_FUNC_QUALIFIER delimeter<CTy>::delimeter(CTy a, CTy b, CTy c)
  79. : value()
  80. {
  81. value[0] = a;
  82. value[1] = b;
  83. value[2] = c;
  84. }
  85. GLM_FUNC_QUALIFIER order::order(order_type a)
  86. : value(a)
  87. {}
  88. template<typename FTy, typename CTy, typename CTr>
  89. GLM_FUNC_QUALIFIER FTy const& get_facet(std::basic_ios<CTy, CTr>& ios)
  90. {
  91. if(!std::has_facet<FTy>(ios.getloc()))
  92. ios.imbue(std::locale(ios.getloc(), new FTy));
  93. return std::use_facet<FTy>(ios.getloc());
  94. }
  95. template<typename CTy, typename CTr>
  96. GLM_FUNC_QUALIFIER std::basic_ios<CTy, CTr>& formatted(std::basic_ios<CTy, CTr>& ios)
  97. {
  98. const_cast<format_punct<CTy>&>(get_facet<format_punct<CTy> >(ios)).formatted = true;
  99. return ios;
  100. }
  101. template<typename CTy, typename CTr>
  102. GLM_FUNC_QUALIFIER std::basic_ios<CTy, CTr>& unformatted(std::basic_ios<CTy, CTr>& ios)
  103. {
  104. const_cast<format_punct<CTy>&>(get_facet<format_punct<CTy> >(ios)).formatted = false;
  105. return ios;
  106. }
  107. template<typename CTy, typename CTr>
  108. GLM_FUNC_QUALIFIER std::basic_ostream<CTy, CTr>& operator<<(std::basic_ostream<CTy, CTr>& os, precision const& a)
  109. {
  110. const_cast<format_punct<CTy>&>(get_facet<format_punct<CTy> >(os)).precision = a.value;
  111. return os;
  112. }
  113. template<typename CTy, typename CTr>
  114. GLM_FUNC_QUALIFIER std::basic_ostream<CTy, CTr>& operator<<(std::basic_ostream<CTy, CTr>& os, width const& a)
  115. {
  116. const_cast<format_punct<CTy>&>(get_facet<format_punct<CTy> >(os)).width = a.value;
  117. return os;
  118. }
  119. template<typename CTy, typename CTr>
  120. GLM_FUNC_QUALIFIER std::basic_ostream<CTy, CTr>& operator<<(std::basic_ostream<CTy, CTr>& os, delimeter<CTy> const& a)
  121. {
  122. format_punct<CTy> & fmt(const_cast<format_punct<CTy>&>(get_facet<format_punct<CTy> >(os)));
  123. fmt.delim_left = a.value[0];
  124. fmt.delim_right = a.value[1];
  125. fmt.separator = a.value[2];
  126. return os;
  127. }
  128. template<typename CTy, typename CTr>
  129. GLM_FUNC_QUALIFIER std::basic_ostream<CTy, CTr>& operator<<(std::basic_ostream<CTy, CTr>& os, order const& a)
  130. {
  131. const_cast<format_punct<CTy>&>(get_facet<format_punct<CTy> >(os)).order = a.value;
  132. return os;
  133. }
  134. } // namespace io
  135. namespace detail
  136. {
  137. template<typename CTy, typename CTr, typename V>
  138. GLM_FUNC_QUALIFIER std::basic_ostream<CTy, CTr>&
  139. print_vector_on(std::basic_ostream<CTy, CTr>& os, V const& a)
  140. {
  141. typename std::basic_ostream<CTy, CTr>::sentry const cerberus(os);
  142. if(cerberus)
  143. {
  144. io::format_punct<CTy> const& fmt(io::get_facet<io::format_punct<CTy> >(os));
  145. length_t const& components(type<V>::components);
  146. if(fmt.formatted)
  147. {
  148. io::basic_state_saver<CTy> const bss(os);
  149. os << std::fixed << std::right << std::setprecision(static_cast<std::streamsize>(fmt.precision)) << std::setfill(fmt.space) << fmt.delim_left;
  150. for(length_t i(0); i < components; ++i)
  151. {
  152. os << std::setw(static_cast<int>(fmt.width)) << a[i];
  153. if(components-1 != i)
  154. os << fmt.separator;
  155. }
  156. os << fmt.delim_right;
  157. }
  158. else
  159. {
  160. for(length_t i(0); i < components; ++i)
  161. {
  162. os << a[i];
  163. if(components-1 != i)
  164. os << fmt.space;
  165. }
  166. }
  167. }
  168. return os;
  169. }
  170. }//namespace detail
  171. template<typename CTy, typename CTr, typename T, qualifier Q>
  172. GLM_FUNC_QUALIFIER std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>& os, qua<T, Q> const& a)
  173. {
  174. return detail::print_vector_on(os, a);
  175. }
  176. template<typename CTy, typename CTr, typename T, qualifier Q>
  177. GLM_FUNC_QUALIFIER std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>& os, vec<1, T, Q> const& a)
  178. {
  179. return detail::print_vector_on(os, a);
  180. }
  181. template<typename CTy, typename CTr, typename T, qualifier Q>
  182. GLM_FUNC_QUALIFIER std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>& os, vec<2, T, Q> const& a)
  183. {
  184. return detail::print_vector_on(os, a);
  185. }
  186. template<typename CTy, typename CTr, typename T, qualifier Q>
  187. GLM_FUNC_QUALIFIER std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>& os, vec<3, T, Q> const& a)
  188. {
  189. return detail::print_vector_on(os, a);
  190. }
  191. template<typename CTy, typename CTr, typename T, qualifier Q>
  192. GLM_FUNC_QUALIFIER std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>& os, vec<4, T, Q> const& a)
  193. {
  194. return detail::print_vector_on(os, a);
  195. }
  196. namespace detail
  197. {
  198. template<typename CTy, typename CTr, template<length_t, length_t, typename, qualifier> class M, length_t C, length_t R, typename T, qualifier Q>
  199. GLM_FUNC_QUALIFIER std::basic_ostream<CTy, CTr>& print_matrix_on(std::basic_ostream<CTy, CTr>& os, M<C, R, T, Q> const& a)
  200. {
  201. typename std::basic_ostream<CTy,CTr>::sentry const cerberus(os);
  202. if(cerberus)
  203. {
  204. io::format_punct<CTy> const& fmt(io::get_facet<io::format_punct<CTy> >(os));
  205. length_t const& cols(type<M<C, R, T, Q> >::cols);
  206. length_t const& rows(type<M<C, R, T, Q> >::rows);
  207. if(fmt.formatted)
  208. {
  209. os << fmt.newline << fmt.delim_left;
  210. switch(fmt.order)
  211. {
  212. case io::column_major:
  213. {
  214. for(length_t i(0); i < rows; ++i)
  215. {
  216. if (0 != i)
  217. os << fmt.space;
  218. os << row(a, i);
  219. if(rows-1 != i)
  220. os << fmt.newline;
  221. }
  222. }
  223. break;
  224. case io::row_major:
  225. {
  226. for(length_t i(0); i < cols; ++i)
  227. {
  228. if(0 != i)
  229. os << fmt.space;
  230. os << column(a, i);
  231. if(cols-1 != i)
  232. os << fmt.newline;
  233. }
  234. }
  235. break;
  236. }
  237. os << fmt.delim_right;
  238. }
  239. else
  240. {
  241. switch (fmt.order)
  242. {
  243. case io::column_major:
  244. {
  245. for(length_t i(0); i < cols; ++i)
  246. {
  247. os << column(a, i);
  248. if(cols - 1 != i)
  249. os << fmt.space;
  250. }
  251. }
  252. break;
  253. case io::row_major:
  254. {
  255. for (length_t i(0); i < rows; ++i)
  256. {
  257. os << row(a, i);
  258. if (rows-1 != i)
  259. os << fmt.space;
  260. }
  261. }
  262. break;
  263. }
  264. }
  265. }
  266. return os;
  267. }
  268. }//namespace detail
  269. template<typename CTy, typename CTr, typename T, qualifier Q>
  270. GLM_FUNC_QUALIFIER std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>& os, mat<2, 2, T, Q> const& a)
  271. {
  272. return detail::print_matrix_on(os, a);
  273. }
  274. template<typename CTy, typename CTr, typename T, qualifier Q>
  275. GLM_FUNC_QUALIFIER std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>& os, mat<2, 3, T, Q> const& a)
  276. {
  277. return detail::print_matrix_on(os, a);
  278. }
  279. template<typename CTy, typename CTr, typename T, qualifier Q>
  280. GLM_FUNC_QUALIFIER std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>& os, mat<2, 4, T, Q> const& a)
  281. {
  282. return detail::print_matrix_on(os, a);
  283. }
  284. template<typename CTy, typename CTr, typename T, qualifier Q>
  285. GLM_FUNC_QUALIFIER std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>& os, mat<3, 2, T, Q> const& a)
  286. {
  287. return detail::print_matrix_on(os, a);
  288. }
  289. template<typename CTy, typename CTr, typename T, qualifier Q>
  290. GLM_FUNC_QUALIFIER std::basic_ostream<CTy,CTr>& operator<<(std::basic_ostream<CTy,CTr>& os, mat<3, 3, T, Q> const& a)
  291. {
  292. return detail::print_matrix_on(os, a);
  293. }
  294. template<typename CTy, typename CTr, typename T, qualifier Q>
  295. GLM_FUNC_QUALIFIER std::basic_ostream<CTy,CTr> & operator<<(std::basic_ostream<CTy,CTr>& os, mat<3, 4, T, Q> const& a)
  296. {
  297. return detail::print_matrix_on(os, a);
  298. }
  299. template<typename CTy, typename CTr, typename T, qualifier Q>
  300. GLM_FUNC_QUALIFIER std::basic_ostream<CTy,CTr> & operator<<(std::basic_ostream<CTy,CTr>& os, mat<4, 2, T, Q> const& a)
  301. {
  302. return detail::print_matrix_on(os, a);
  303. }
  304. template<typename CTy, typename CTr, typename T, qualifier Q>
  305. GLM_FUNC_QUALIFIER std::basic_ostream<CTy,CTr> & operator<<(std::basic_ostream<CTy,CTr>& os, mat<4, 3, T, Q> const& a)
  306. {
  307. return detail::print_matrix_on(os, a);
  308. }
  309. template<typename CTy, typename CTr, typename T, qualifier Q>
  310. GLM_FUNC_QUALIFIER std::basic_ostream<CTy,CTr> & operator<<(std::basic_ostream<CTy,CTr>& os, mat<4, 4, T, Q> const& a)
  311. {
  312. return detail::print_matrix_on(os, a);
  313. }
  314. namespace detail
  315. {
  316. template<typename CTy, typename CTr, template<length_t, length_t, typename, qualifier> class M, length_t C, length_t R, typename T, qualifier Q>
  317. GLM_FUNC_QUALIFIER std::basic_ostream<CTy, CTr>& print_matrix_pair_on(std::basic_ostream<CTy, CTr>& os, std::pair<M<C, R, T, Q> const, M<C, R, T, Q> const> const& a)
  318. {
  319. typename std::basic_ostream<CTy,CTr>::sentry const cerberus(os);
  320. if(cerberus)
  321. {
  322. io::format_punct<CTy> const& fmt(io::get_facet<io::format_punct<CTy> >(os));
  323. M<C, R, T, Q> const& ml(a.first);
  324. M<C, R, T, Q> const& mr(a.second);
  325. length_t const& cols(type<M<C, R, T, Q> >::cols);
  326. length_t const& rows(type<M<C, R, T, Q> >::rows);
  327. if(fmt.formatted)
  328. {
  329. os << fmt.newline << fmt.delim_left;
  330. switch(fmt.order)
  331. {
  332. case io::column_major:
  333. {
  334. for(length_t i(0); i < rows; ++i)
  335. {
  336. if(0 != i)
  337. os << fmt.space;
  338. os << row(ml, i) << ((rows-1 != i) ? fmt.space : fmt.delim_right) << fmt.space << ((0 != i) ? fmt.space : fmt.delim_left) << row(mr, i);
  339. if(rows-1 != i)
  340. os << fmt.newline;
  341. }
  342. }
  343. break;
  344. case io::row_major:
  345. {
  346. for(length_t i(0); i < cols; ++i)
  347. {
  348. if(0 != i)
  349. os << fmt.space;
  350. os << column(ml, i) << ((cols-1 != i) ? fmt.space : fmt.delim_right) << fmt.space << ((0 != i) ? fmt.space : fmt.delim_left) << column(mr, i);
  351. if(cols-1 != i)
  352. os << fmt.newline;
  353. }
  354. }
  355. break;
  356. }
  357. os << fmt.delim_right;
  358. }
  359. else
  360. {
  361. os << ml << fmt.space << mr;
  362. }
  363. }
  364. return os;
  365. }
  366. }//namespace detail
  367. template<typename CTy, typename CTr, typename T, qualifier Q>
  368. GLM_FUNC_QUALIFIER std::basic_ostream<CTy, CTr>& operator<<(
  369. std::basic_ostream<CTy, CTr> & os,
  370. std::pair<mat<4, 4, T, Q> const,
  371. mat<4, 4, T, Q> const> const& a)
  372. {
  373. return detail::print_matrix_pair_on(os, a);
  374. }
  375. }//namespace glm
  376. #if GLM_COMPILER & GLM_COMPILER_CLANG
  377. # pragma clang diagnostic pop
  378. #endif