/// @ref gtx_io /// @file glm/gtx/io.inl /// @author Jan P Springer (regnirpsj@gmail.com) #include // std::fixed, std::setfill<>, std::setprecision, std::right, std::setw #include // std::basic_ostream<> #include "../gtc/matrix_access.hpp" // glm::col, glm::row #include "../gtx/type_trait.hpp" // glm::type<> namespace glm{ namespace io { template GLM_FUNC_QUALIFIER format_punct::format_punct(size_t a) : std::locale::facet(a) , formatted(true) , precision(3) , width(1 + 4 + 1 + precision) , separator(',') , delim_left('[') , delim_right(']') , space(' ') , newline('\n') , order(column_major) {} template GLM_FUNC_QUALIFIER format_punct::format_punct(format_punct const& a) : std::locale::facet(0) , formatted(a.formatted) , precision(a.precision) , width(a.width) , separator(a.separator) , delim_left(a.delim_left) , delim_right(a.delim_right) , space(a.space) , newline(a.newline) , order(a.order) {} template std::locale::id format_punct::id; template GLM_FUNC_QUALIFIER basic_state_saver::basic_state_saver(std::basic_ios& a) : state_(a) , flags_(a.flags()) , precision_(a.precision()) , width_(a.width()) , fill_(a.fill()) , locale_(a.getloc()) {} template GLM_FUNC_QUALIFIER basic_state_saver::~basic_state_saver() { state_.imbue(locale_); state_.fill(fill_); state_.width(width_); state_.precision(precision_); state_.flags(flags_); } template GLM_FUNC_QUALIFIER basic_format_saver::basic_format_saver(std::basic_ios& a) : bss_(a) { a.imbue(std::locale(a.getloc(), new format_punct(get_facet >(a)))); } template GLM_FUNC_QUALIFIER basic_format_saver::~basic_format_saver() {} GLM_FUNC_QUALIFIER precision::precision(unsigned a) : value(a) {} GLM_FUNC_QUALIFIER width::width(unsigned a) : value(a) {} template GLM_FUNC_QUALIFIER delimeter::delimeter(CTy a, CTy b, CTy c) : value() { value[0] = a; value[1] = b; value[2] = c; } GLM_FUNC_QUALIFIER order::order(order_type a) : value(a) {} template GLM_FUNC_QUALIFIER FTy const& get_facet(std::basic_ios& ios) { if(!std::has_facet(ios.getloc())) ios.imbue(std::locale(ios.getloc(), new FTy)); return std::use_facet(ios.getloc()); } template GLM_FUNC_QUALIFIER std::basic_ios& formatted(std::basic_ios& ios) { const_cast&>(get_facet >(ios)).formatted = true; return ios; } template GLM_FUNC_QUALIFIER std::basic_ios& unformatted(std::basic_ios& ios) { const_cast&>(get_facet >(ios)).formatted = false; return ios; } template GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, precision const& a) { const_cast&>(get_facet >(os)).precision = a.value; return os; } template GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, width const& a) { const_cast&>(get_facet >(os)).width = a.value; return os; } template GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, delimeter const& a) { format_punct & fmt(const_cast&>(get_facet >(os))); fmt.delim_left = a.value[0]; fmt.delim_right = a.value[1]; fmt.separator = a.value[2]; return os; } template GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, order const& a) { const_cast&>(get_facet >(os)).order = a.value; return os; } } // namespace io namespace detail { template class V, typename T, precision P> GLM_FUNC_QUALIFIER std::basic_ostream& print_vector_on(std::basic_ostream& os, V const& a) { typename std::basic_ostream::sentry const cerberus(os); if(cerberus) { io::format_punct const & fmt(io::get_facet >(os)); length_t const& components(type::components); if(fmt.formatted) { io::basic_state_saver const bss(os); os << std::fixed << std::right << std::setprecision(fmt.precision) << std::setfill(fmt.space) << fmt.delim_left; for(length_t i(0); i < components; ++i) { os << std::setw(fmt.width) << a[i]; if(components-1 != i) os << fmt.separator; } os << fmt.delim_right; } else { for(length_t i(0); i < components; ++i) { os << a[i]; if(components-1 != i) os << fmt.space; } } } return os; } }//namespace detail template GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tquat const& a) { return detail::print_vector_on(os, a); } template GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tvec1 const& a) { return detail::print_vector_on(os, a); } template GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tvec2 const& a) { return detail::print_vector_on(os, a); } template GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tvec3 const& a) { return detail::print_vector_on(os, a); } template GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tvec4 const& a) { return detail::print_vector_on(os, a); } namespace detail { template class M, typename T, precision P> GLM_FUNC_QUALIFIER std::basic_ostream& print_matrix_on(std::basic_ostream& os, M const& a) { typename std::basic_ostream::sentry const cerberus(os); if(cerberus) { io::format_punct const & fmt(io::get_facet >(os)); length_t const& cols(type::cols); length_t const& rows(type::rows); if(fmt.formatted) { os << fmt.newline << fmt.delim_left; switch(fmt.order) { case io::column_major: { for(length_t i(0); i < rows; ++i) { if (0 != i) os << fmt.space; os << row(a, i); if(rows-1 != i) os << fmt.newline; } } break; case io::row_major: { for(length_t i(0); i < cols; ++i) { if(0 != i) os << fmt.space; os << column(a, i); if(cols-1 != i) os << fmt.newline; } } break; } os << fmt.delim_right; } else { switch (fmt.order) { case io::column_major: { for(length_t i(0); i < cols; ++i) { os << column(a, i); if(cols - 1 != i) os << fmt.space; } } break; case io::row_major: { for (length_t i(0); i < rows; ++i) { os << row(a, i); if (rows-1 != i) os << fmt.space; } } break; } } } return os; } }//namespace detail template GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tmat2x2 const& a) { return detail::print_matrix_on(os, a); } template GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tmat2x3 const& a) { return detail::print_matrix_on(os, a); } template GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tmat2x4 const& a) { return detail::print_matrix_on(os, a); } template GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tmat3x2 const& a) { return detail::print_matrix_on(os, a); } template GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tmat3x3 const& a) { return detail::print_matrix_on(os, a); } template GLM_FUNC_QUALIFIER std::basic_ostream & operator<<(std::basic_ostream& os, tmat3x4 const& a) { return detail::print_matrix_on(os, a); } template GLM_FUNC_QUALIFIER std::basic_ostream & operator<<(std::basic_ostream& os, tmat4x2 const& a) { return detail::print_matrix_on(os, a); } template GLM_FUNC_QUALIFIER std::basic_ostream & operator<<(std::basic_ostream& os, tmat4x3 const& a) { return detail::print_matrix_on(os, a); } template GLM_FUNC_QUALIFIER std::basic_ostream & operator<<(std::basic_ostream& os, tmat4x4 const& a) { return detail::print_matrix_on(os, a); } namespace detail { template class M, typename T, precision P> GLM_FUNC_QUALIFIER std::basic_ostream& print_matrix_pair_on(std::basic_ostream& os, std::pair const, M const> const& a) { typename std::basic_ostream::sentry const cerberus(os); if(cerberus) { io::format_punct const& fmt(io::get_facet >(os)); M const& ml(a.first); M const& mr(a.second); length_t const& cols(type::cols); length_t const& rows(type::rows); if(fmt.formatted) { os << fmt.newline << fmt.delim_left; switch(fmt.order) { case io::column_major: { for(length_t i(0); i < rows; ++i) { if(0 != i) os << fmt.space; os << row(ml, i) << ((rows-1 != i) ? fmt.space : fmt.delim_right) << fmt.space << ((0 != i) ? fmt.space : fmt.delim_left) << row(mr, i); if(rows-1 != i) os << fmt.newline; } } break; case io::row_major: { for(length_t i(0); i < cols; ++i) { if(0 != i) os << fmt.space; os << column(ml, i) << ((cols-1 != i) ? fmt.space : fmt.delim_right) << fmt.space << ((0 != i) ? fmt.space : fmt.delim_left) << column(mr, i); if(cols-1 != i) os << fmt.newline; } } break; } os << fmt.delim_right; } else { os << ml << fmt.space << mr; } } return os; } }//namespace detail template GLM_FUNC_QUALIFIER std::basic_ostream& operator<<( std::basic_ostream & os, std::pair const, tmat4x4 const> const& a) { return detail::print_matrix_pair_on(os, a); } }//namespace glm