9
3

io.inl 12 KB

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