Collection of DPF-based plugins for packaging
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

442 lines
12KB

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