diff --git a/glm/gtx/io.hpp b/glm/gtx/io.hpp index 25e9d74b..7dd22182 100644 --- a/glm/gtx/io.hpp +++ b/glm/gtx/io.hpp @@ -57,178 +57,168 @@ namespace glm { - /// @addtogroup gtx_io - /// @{ - - namespace io - { - - enum order_type { column_major, row_major, }; - - template - class format_punct : public std::locale::facet { + /// @addtogroup gtx_io + /// @{ - typedef CTy char_type; - - public: + namespace io + { + enum order_type { column_major, row_major}; - static std::locale::id id; + template + class format_punct : public std::locale::facet + { + typedef CTy char_type; - bool formatted; - unsigned precision; - unsigned width; - char_type separator; - char_type delim_left; - char_type delim_right; - char_type space; - char_type newline; - order_type order; - - explicit format_punct(size_t a = 0); - explicit format_punct(format_punct const&); - - }; + public: - template > - class basic_state_saver { + static std::locale::id id; - public: + bool formatted; + unsigned precision; + unsigned width; + char_type separator; + char_type delim_left; + char_type delim_right; + char_type space; + char_type newline; + order_type order; - explicit basic_state_saver(std::basic_ios&); - ~basic_state_saver(); + explicit format_punct(size_t a = 0); + explicit format_punct(format_punct const&); + }; - private: + template > + class basic_state_saver { - typedef ::std::basic_ios state_type; - typedef typename state_type::char_type char_type; - typedef ::std::ios_base::fmtflags flags_type; - typedef ::std::streamsize streamsize_type; - typedef ::std::locale const locale_type; - - state_type& state_; - flags_type flags_; - streamsize_type precision_; - streamsize_type width_; - char_type fill_; - locale_type locale_; - - basic_state_saver& operator=(basic_state_saver const&); - - }; + public: - typedef basic_state_saver state_saver; - typedef basic_state_saver wstate_saver; - - template > - class basic_format_saver { + explicit basic_state_saver(std::basic_ios&); + ~basic_state_saver(); - public: + private: - explicit basic_format_saver(std::basic_ios&); - ~basic_format_saver(); + typedef ::std::basic_ios state_type; + typedef typename state_type::char_type char_type; + typedef ::std::ios_base::fmtflags flags_type; + typedef ::std::streamsize streamsize_type; + typedef ::std::locale const locale_type; - private: + state_type& state_; + flags_type flags_; + streamsize_type precision_; + streamsize_type width_; + char_type fill_; + locale_type locale_; - basic_state_saver const bss_; + basic_state_saver& operator=(basic_state_saver const&); + }; - basic_format_saver& operator=(basic_format_saver const&); - - }; + typedef basic_state_saver state_saver; + typedef basic_state_saver wstate_saver; - typedef basic_format_saver format_saver; - typedef basic_format_saver wformat_saver; - - struct precision { + template > + class basic_format_saver + { + public: - unsigned value; - - explicit precision(unsigned); - - }; + explicit basic_format_saver(std::basic_ios&); + ~basic_format_saver(); - struct width { + private: - unsigned value; - - explicit width(unsigned); - - }; + basic_state_saver const bss_; - template - struct delimeter { + basic_format_saver& operator=(basic_format_saver const&); + }; - CTy value[3]; - - explicit delimeter(CTy /* left */, CTy /* right */, CTy /* separator */ = ','); - - }; + typedef basic_format_saver format_saver; + typedef basic_format_saver wformat_saver; - struct order { + struct precision + { + unsigned value; - order_type value; - - explicit order(order_type); - - }; - - // functions, inlined (inline) + explicit precision(unsigned); + }; - template - FTy const& get_facet(std::basic_ios&); - template - std::basic_ios& formatted(std::basic_ios&); - template - std::basic_ios& unformattet(std::basic_ios&); - - template - std::basic_ostream& operator<<(std::basic_ostream&, precision const&); - template - std::basic_ostream& operator<<(std::basic_ostream&, width const&); - template - std::basic_ostream& operator<<(std::basic_ostream&, delimeter const&); - template - std::basic_ostream& operator<<(std::basic_ostream&, order const&); - - }//namespace io + struct width + { + unsigned value; - namespace detail - { + explicit width(unsigned); + }; - template - GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, tquat const&); - template - GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, tvec2 const&); - template - GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, tvec3 const&); - template - GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, tvec4 const&); - template - GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, tmat2x2 const&); - template - GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, tmat2x3 const&); - template - GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, tmat2x4 const&); - template - GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, tmat3x2 const&); - template - GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, tmat3x3 const&); - template - GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, tmat3x4 const&); - template - GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, tmat4x2 const&); - template - GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, tmat4x3 const&); - template - GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, tmat4x4 const&); - - template - GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, - std::pair const, - tmat4x4 const> const&); - - }//namespace detail - - /// @} + template + struct delimeter + { + CTy value[3]; + + explicit delimeter(CTy /* left */, CTy /* right */, CTy /* separator */ = ','); + }; + + struct order + { + order_type value; + + explicit order(order_type); + }; + + // functions, inlined (inline) + + template + FTy const& get_facet(std::basic_ios&); + template + std::basic_ios& formatted(std::basic_ios&); + template + std::basic_ios& unformattet(std::basic_ios&); + + template + std::basic_ostream& operator<<(std::basic_ostream&, precision const&); + template + std::basic_ostream& operator<<(std::basic_ostream&, width const&); + template + std::basic_ostream& operator<<(std::basic_ostream&, delimeter const&); + template + std::basic_ostream& operator<<(std::basic_ostream&, order const&); + }//namespace io + + namespace detail + { + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, tquat const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, tvec2 const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, tvec3 const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, tvec4 const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, tmat2x2 const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, tmat2x3 const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, tmat2x4 const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, tmat3x2 const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, tmat3x3 const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, tmat3x4 const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, tmat4x2 const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, tmat4x3 const&); + template + GLM_FUNC_DECL std::basic_ostream& operator<<(std::basic_ostream&, tmat4x4 const&); + + template + GLM_FUNC_DECL std::basic_ostream & operator<<( + std::basic_ostream &, + std::pair const, + tmat4x4 const> const &); + }//namespace detail + + /// @} }//namespace glm #include "io.inl" diff --git a/glm/gtx/io.inl b/glm/gtx/io.inl index 3132a88e..dbad163c 100644 --- a/glm/gtx/io.inl +++ b/glm/gtx/io.inl @@ -10,570 +10,589 @@ #include // std::setfill<>, std::fixed, std::setprecision, std::right, std::setw #include // std::basic_ostream<> -namespace glm +namespace glm{ +namespace io { - namespace io - { - - template - /* explicit */ 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 (row_major) - {} - - template - /* explicit */ 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 - /* explicit */ 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 - /* explicit */ 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() - {} - - /* explicit */ GLM_FUNC_QUALIFIER - precision::precision(unsigned a) - : value(a) - {} - - /* explicit */ GLM_FUNC_QUALIFIER - width::width(unsigned a) - : value(a) - {} - - template - /* explicit */ GLM_FUNC_QUALIFIER - delimeter::delimeter(CTy a, CTy b, CTy c) - : value() - { - value[0] = a; - value[1] = b; - value[2] = c; - } - - /* explicit */ 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 - 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 - GLM_FUNC_QUALIFIER std::basic_ostream& - operator<<(std::basic_ostream& os, tquat const& a) - { - typename std::basic_ostream::sentry const cerberus(os); - - if (cerberus) { - io::format_punct const& fmt(io::get_facet >(os)); - - 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 - << std::setw(fmt.width) << a.w << fmt.separator - << std::setw(fmt.width) << a.x << fmt.separator - << std::setw(fmt.width) << a.y << fmt.separator - << std::setw(fmt.width) << a.z - << fmt.delim_right; - } else { - os << a.w << fmt.space << a.x << fmt.space << a.y << fmt.space << a.z; - } - } - - return os; - } - - template - GLM_FUNC_QUALIFIER std::basic_ostream& - operator<<(std::basic_ostream& os, tvec2 const& a) - { - typename std::basic_ostream::sentry const cerberus(os); - - if (cerberus) { - io::format_punct const& fmt(io::get_facet >(os)); - - 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 - << std::setw(fmt.width) << a.x << fmt.separator - << std::setw(fmt.width) << a.y - << fmt.delim_right; - } else { - os << a.x << fmt.space << a.y; - } - } - - return os; - } - - template - GLM_FUNC_QUALIFIER std::basic_ostream& - operator<<(std::basic_ostream& os, tvec3 const& a) - { - typename std::basic_ostream::sentry const cerberus(os); - - if (cerberus) { - io::format_punct const& fmt(io::get_facet >(os)); - - 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 - << std::setw(fmt.width) << a.x << fmt.separator - << std::setw(fmt.width) << a.y << fmt.separator - << std::setw(fmt.width) << a.z - << fmt.delim_right; - } else { - os << a.x << fmt.space << a.y << fmt.space << a.z; - } - } - - return os; - } - - template - GLM_FUNC_QUALIFIER std::basic_ostream& - operator<<(std::basic_ostream& os, tvec4 const& a) - { - typename std::basic_ostream::sentry const cerberus(os); - - if (cerberus) { - io::format_punct const& fmt(io::get_facet >(os)); - - 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 - << std::setw(fmt.width) << a.x << fmt.separator - << std::setw(fmt.width) << a.y << fmt.separator - << std::setw(fmt.width) << a.z << fmt.separator - << std::setw(fmt.width) << a.w - << fmt.delim_right; - } else { - os << a.x << fmt.space << a.y << fmt.space << a.z << fmt.space << a.w; - } - } - - return os; - } - - template - GLM_FUNC_QUALIFIER std::basic_ostream& - operator<<(std::basic_ostream& os, tmat2x2 const& a) - { - typename std::basic_ostream::sentry const cerberus(os); - - if (cerberus) { - io::format_punct const& fmt(io::get_facet >(os)); - tmat2x2 m(a); - - if (io::row_major == fmt.order) { - m = transpose(a); - } - - if (fmt.formatted) { - os << fmt.newline - << fmt.delim_left << m[0] << fmt.newline - << fmt.space << m[1] << fmt.delim_right; - } else { - os << m[0] << fmt.space << m[1]; - } - } - - return os; - } - - template - GLM_FUNC_QUALIFIER std::basic_ostream& - operator<<(std::basic_ostream& os, tmat2x3 const& a) - { - typename std::basic_ostream::sentry const cerberus(os); - - if (cerberus) { - io::format_punct const& fmt(io::get_facet >(os)); - tmat3x2 m(a); - - if (io::row_major == fmt.order) { - m = transpose(a); - } - - if (fmt.formatted) { - os << fmt.newline - << fmt.delim_left << m[0] << fmt.newline - << fmt.space << m[1] << fmt.newline - << fmt.space << m[2] << fmt.delim_right; - } else { - os << m[0] << fmt.space << m[1] << fmt.space << m[2]; - } - } - - return os; - } - - template - GLM_FUNC_QUALIFIER std::basic_ostream& - operator<<(std::basic_ostream& os, tmat2x4 const& a) - { - typename std::basic_ostream::sentry const cerberus(os); - - if (cerberus) { - io::format_punct const& fmt(io::get_facet >(os)); - tmat4x2 m(a); - - if (io::row_major == fmt.order) { - m = transpose(a); - } - - if (fmt.formatted) { - os << fmt.newline - << fmt.delim_left << m[0] << fmt.newline - << fmt.space << m[1] << fmt.newline - << fmt.space << m[2] << fmt.newline - << fmt.space << m[3] << fmt.delim_right; - } else { - os << m[0] << fmt.space << m[1] << fmt.space << m[2] << fmt.space << m[3]; - } - } - - return os; - } - - template - GLM_FUNC_QUALIFIER std::basic_ostream& - operator<<(std::basic_ostream& os, tmat3x2 const& a) - { - typename std::basic_ostream::sentry const cerberus(os); - - if (cerberus) { - io::format_punct const& fmt(io::get_facet >(os)); - tmat2x3 m(a); - - if (io::row_major == fmt.order) { - m = transpose(a); - } - - if (fmt.formatted) { - os << fmt.newline - << fmt.delim_left << m[0] << fmt.newline - << fmt.space << m[1] << fmt.delim_right; - } else { - os << m[0] << fmt.space << m[1]; - } - } - - return os; - } - - template - GLM_FUNC_QUALIFIER std::basic_ostream& - operator<<(std::basic_ostream& os, tmat3x3 const& a) - { - typename std::basic_ostream::sentry const cerberus(os); - - if (cerberus) { - io::format_punct const& fmt(io::get_facet >(os)); - tmat3x3 m(a); - - if (io::row_major == fmt.order) { - m = transpose(a); - } - - if (fmt.formatted) { - os << fmt.newline - << fmt.delim_left << m[0] << fmt.newline - << fmt.space << m[1] << fmt.newline - << fmt.space << m[2] << fmt.delim_right; - } else { - os << m[0] << fmt.space << m[1] << fmt.space << m[2]; - } - } - - return os; - } - - template - GLM_FUNC_QUALIFIER std::basic_ostream& - operator<<(std::basic_ostream& os, tmat3x4 const& a) - { - typename std::basic_ostream::sentry const cerberus(os); - - if (cerberus) { - io::format_punct const& fmt(io::get_facet >(os)); - tmat4x3 m(a); - - if (io::row_major == fmt.order) { - m = transpose(a); - } - - if (fmt.formatted) { - os << fmt.newline - << fmt.delim_left << m[0] << fmt.newline - << fmt.space << m[1] << fmt.newline - << fmt.space << m[2] << fmt.newline - << fmt.space << m[3] << fmt.delim_right; - } else { - os << m[0] << fmt.space << m[1] << fmt.space << m[2] << fmt.space << m[3]; - } - } - - return os; - } - - template - GLM_FUNC_QUALIFIER std::basic_ostream& - operator<<(std::basic_ostream& os, tmat4x2 const& a) - { - typename std::basic_ostream::sentry const cerberus(os); - - if (cerberus) { - io::format_punct const& fmt(io::get_facet >(os)); - tmat2x4 m(a); - - if (io::row_major == fmt.order) { - m = transpose(a); - } - - if (fmt.formatted) { - os << fmt.newline - << fmt.delim_left << m[0] << fmt.newline - << fmt.space << m[1] << fmt.delim_right; - } else { - os << m[0] << fmt.space << m[1]; - } - } - - return os; - } - - template - GLM_FUNC_QUALIFIER std::basic_ostream& - operator<<(std::basic_ostream& os, tmat4x3 const& a) - { - typename std::basic_ostream::sentry const cerberus(os); - - if (cerberus) { - io::format_punct const& fmt(io::get_facet >(os)); - tmat3x4 m(a); - - if (io::row_major == fmt.order) { - m = transpose(a); - } - - if (fmt.formatted) { - os << fmt.newline - << fmt.delim_left << m[0] << fmt.newline - << fmt.space << m[1] << fmt.newline - << fmt.space << m[2] << fmt.delim_right; - } else { - os << m[0] << fmt.space << m[1] << fmt.space << m[2]; - } - } - - return os; - } - - template - GLM_FUNC_QUALIFIER std::basic_ostream& - operator<<(std::basic_ostream& os, tmat4x4 const& a) - { - typename std::basic_ostream::sentry const cerberus(os); - - if (cerberus) { - io::format_punct const& fmt(io::get_facet >(os)); - tmat4x4 m(a); - - if (io::row_major == fmt.order) { - m = transpose(a); - } - - if (fmt.formatted) { - os << fmt.newline - << fmt.delim_left << m[0] << fmt.newline - << fmt.space << m[1] << fmt.newline - << fmt.space << m[2] << fmt.newline - << fmt.space << m[3] << fmt.delim_right; - } else { - os << m[0] << fmt.space << m[1] << fmt.space << m[2] << fmt.space << m[3]; - } - } - - return os; - } - - template - GLM_FUNC_QUALIFIER std::basic_ostream& - operator<<(std::basic_ostream& os, - std::pair const, tmat4x4 const> const& a) - { - typename std::basic_ostream::sentry const cerberus(os); - - if (cerberus) { - io::format_punct const& fmt(io::get_facet >(os)); - tmat4x4 ml(a.first); - tmat4x4 mr(a.second); - - if (io::row_major == fmt.order) { - ml = transpose(a.first); - mr = transpose(a.second); - } - - if (fmt.formatted) { - CTy const& l(fmt.delim_left); - CTy const& r(fmt.delim_right); - CTy const& s(fmt.space); - - os << fmt.newline - << l << ml[0] << s << s << l << mr[0] << fmt.newline - << s << ml[1] << s << s << s << mr[1] << fmt.newline - << s << ml[2] << s << s << s << mr[2] << fmt.newline - << s << ml[3] << r << s << s << mr[3] << r; - } else { - os << ml << fmt.space << mr; - } - } - - return os; - } - - }//namespace detail + template + /* explicit */ 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 (row_major) + {} + + template + /* explicit */ 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 + /* explicit */ 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 + /* explicit */ 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() + {} + + /* explicit */ GLM_FUNC_QUALIFIER precision::precision(unsigned a) + : value(a) + {} + + /* explicit */ GLM_FUNC_QUALIFIER width::width(unsigned a) + : value(a) + {} + + template + /* explicit */ GLM_FUNC_QUALIFIER delimeter::delimeter(CTy a, CTy b, CTy c) + : value() + { + value[0] = a; + value[1] = b; + value[2] = c; + } + + /* explicit */ 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 + 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 + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tquat const& a) + { + typename std::basic_ostream::sentry const cerberus(os); + + if(cerberus) + { + io::format_punct const & fmt(io::get_facet >(os)); + + 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 + << std::setw(fmt.width) << a.w << fmt.separator + << std::setw(fmt.width) << a.x << fmt.separator + << std::setw(fmt.width) << a.y << fmt.separator + << std::setw(fmt.width) << a.z + << fmt.delim_right; + } + else + { + os << a.w << fmt.space << a.x << fmt.space << a.y << fmt.space << a.z; + } + } + + return os; + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tvec2 const& a) + { + typename std::basic_ostream::sentry const cerberus(os); + + if(cerberus) + { + io::format_punct const & fmt(io::get_facet >(os)); + + 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 + << std::setw(fmt.width) << a.x << fmt.separator + << std::setw(fmt.width) << a.y + << fmt.delim_right; + } + else + { + os << a.x << fmt.space << a.y; + } + } + + return os; + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tvec3 const& a) + { + typename std::basic_ostream::sentry const cerberus(os); + + if(cerberus) + { + io::format_punct const & fmt(io::get_facet >(os)); + + 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 + << std::setw(fmt.width) << a.x << fmt.separator + << std::setw(fmt.width) << a.y << fmt.separator + << std::setw(fmt.width) << a.z + << fmt.delim_right; + } + else + { + os << a.x << fmt.space << a.y << fmt.space << a.z; + } + } + + return os; + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tvec4 const& a) + { + typename std::basic_ostream::sentry const cerberus(os); + + if(cerberus) + { + io::format_punct const & fmt(io::get_facet >(os)); + + 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 + << std::setw(fmt.width) << a.x << fmt.separator + << std::setw(fmt.width) << a.y << fmt.separator + << std::setw(fmt.width) << a.z << fmt.separator + << std::setw(fmt.width) << a.w + << fmt.delim_right; + } + else + { + os << a.x << fmt.space << a.y << fmt.space << a.z << fmt.space << a.w; + } + } + + return os; + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tmat2x2 const& a) + { + typename std::basic_ostream::sentry const cerberus(os); + + if(cerberus) + { + io::format_punct const & fmt(io::get_facet >(os)); + tmat2x2 m(a); + + if(io::row_major == fmt.order) + m = transpose(a); + + if(fmt.formatted) + { + os << fmt.newline + << fmt.delim_left << m[0] << fmt.newline + << fmt.space << m[1] << fmt.delim_right; + } + else + { + os << m[0] << fmt.space << m[1]; + } + } + + return os; + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tmat2x3 const& a) + { + typename std::basic_ostream::sentry const cerberus(os); + + if(cerberus) + { + io::format_punct const & fmt(io::get_facet >(os)); + tmat3x2 m(a); + + if(io::row_major == fmt.order) + m = transpose(a); + + if(fmt.formatted) + { + os << fmt.newline + << fmt.delim_left << m[0] << fmt.newline + << fmt.space << m[1] << fmt.newline + << fmt.space << m[2] << fmt.delim_right; + } + else + { + os << m[0] << fmt.space << m[1] << fmt.space << m[2]; + } + } + + return os; + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tmat2x4 const& a) + { + typename std::basic_ostream::sentry const cerberus(os); + + if(cerberus) + { + io::format_punct const & fmt(io::get_facet >(os)); + tmat4x2 m(a); + + if(io::row_major == fmt.order) + m = transpose(a); + + + if(fmt.formatted) + { + os << fmt.newline + << fmt.delim_left << m[0] << fmt.newline + << fmt.space << m[1] << fmt.newline + << fmt.space << m[2] << fmt.newline + << fmt.space << m[3] << fmt.delim_right; + } + else + { + os << m[0] << fmt.space << m[1] << fmt.space << m[2] << fmt.space << m[3]; + } + } + + return os; + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tmat3x2 const& a) + { + typename std::basic_ostream::sentry const cerberus(os); + + if(cerberus) + { + io::format_punct const & fmt(io::get_facet >(os)); + tmat2x3 m(a); + + if(io::row_major == fmt.order) + m = transpose(a); + + if(fmt.formatted) + { + os << fmt.newline + << fmt.delim_left << m[0] << fmt.newline + << fmt.space << m[1] << fmt.delim_right; + } + else + { + os << m[0] << fmt.space << m[1]; + } + } + + return os; + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tmat3x3 const& a) + { + typename std::basic_ostream::sentry const cerberus(os); + + if(cerberus) + { + io::format_punct const & fmt(io::get_facet >(os)); + tmat3x3 m(a); + + if(io::row_major == fmt.order) + m = transpose(a); + + if(fmt.formatted) + { + os << fmt.newline + << fmt.delim_left << m[0] << fmt.newline + << fmt.space << m[1] << fmt.newline + << fmt.space << m[2] << fmt.delim_right; + } + else + { + os << m[0] << fmt.space << m[1] << fmt.space << m[2]; + } + } + + return os; + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream & operator<<(std::basic_ostream& os, tmat3x4 const& a) + { + typename std::basic_ostream::sentry const cerberus(os); + + if(cerberus) + { + io::format_punct const & fmt(io::get_facet >(os)); + tmat4x3 m(a); + + if(io::row_major == fmt.order) + m = transpose(a); + + if (fmt.formatted) + { + os << fmt.newline + << fmt.delim_left << m[0] << fmt.newline + << fmt.space << m[1] << fmt.newline + << fmt.space << m[2] << fmt.newline + << fmt.space << m[3] << fmt.delim_right; + } + else + { + os << m[0] << fmt.space << m[1] << fmt.space << m[2] << fmt.space << m[3]; + } + } + + return os; + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream & operator<<(std::basic_ostream& os, tmat4x2 const& a) + { + typename std::basic_ostream::sentry const cerberus(os); + + if(cerberus) + { + io::format_punct const & fmt(io::get_facet >(os)); + tmat2x4 m(a); + + if(io::row_major == fmt.order) + m = transpose(a); + + if (fmt.formatted) + { + os << fmt.newline + << fmt.delim_left << m[0] << fmt.newline + << fmt.space << m[1] << fmt.delim_right; + } + else + { + os << m[0] << fmt.space << m[1]; + } + } + + return os; + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream & operator<<(std::basic_ostream& os, tmat4x3 const& a) + { + typename std::basic_ostream::sentry const cerberus(os); + + if(cerberus) + { + io::format_punct const & fmt(io::get_facet >(os)); + tmat3x4 m(a); + + if(io::row_major == fmt.order) + m = transpose(a); + + if(fmt.formatted) + { + os << fmt.newline + << fmt.delim_left << m[0] << fmt.newline + << fmt.space << m[1] << fmt.newline + << fmt.space << m[2] << fmt.delim_right; + } + else + { + os << m[0] << fmt.space << m[1] << fmt.space << m[2]; + } + } + + return os; + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream & operator<<(std::basic_ostream& os, tmat4x4 const& a) + { + typename std::basic_ostream::sentry const cerberus(os); + + if(cerberus) + { + io::format_punct const & fmt(io::get_facet >(os)); + tmat4x4 m(a); + + if (io::row_major == fmt.order) + m = transpose(a); + + if(fmt.formatted) + { + os << fmt.newline + << fmt.delim_left << m[0] << fmt.newline + << fmt.space << m[1] << fmt.newline + << fmt.space << m[2] << fmt.newline + << fmt.space << m[3] << fmt.delim_right; + } + else + { + os << m[0] << fmt.space << m[1] << fmt.space << m[2] << fmt.space << m[3]; + } + } + + return os; + } + + template + GLM_FUNC_QUALIFIER std::basic_ostream& operator<<( + std::basic_ostream & os, + std::pair const, tmat4x4 const> const& a) + { + typename std::basic_ostream::sentry const cerberus(os); + + if(cerberus) + { + io::format_punct const & fmt(io::get_facet >(os)); + tmat4x4 ml(a.first); + tmat4x4 mr(a.second); + + if(io::row_major == fmt.order) + { + ml = transpose(a.first); + mr = transpose(a.second); + } + + if(fmt.formatted) + { + CTy const & l(fmt.delim_left); + CTy const & r(fmt.delim_right); + CTy const & s(fmt.space); + + os << fmt.newline + << l << ml[0] << s << s << l << mr[0] << fmt.newline + << s << ml[1] << s << s << s << mr[1] << fmt.newline + << s << ml[2] << s << s << s << mr[2] << fmt.newline + << s << ml[3] << r << s << s << mr[3] << r; + } + else + { + os << ml << fmt.space << mr; + } + } + + return os; + } +}//namespace detail }//namespace glm diff --git a/glm/gtx/quaternion.inl b/glm/gtx/quaternion.inl index 2d1a6c13..0dc95b0f 100644 --- a/glm/gtx/quaternion.inl +++ b/glm/gtx/quaternion.inl @@ -8,6 +8,7 @@ /////////////////////////////////////////////////////////////////////////////////////////////////// #include +#include "../gtc/constants.hpp" namespace glm { @@ -40,7 +41,7 @@ namespace glm detail::tquat const & s2, T const & h) { - return mix(mix(q1, q2, h), mix(s1, s2, h), T(2) * (T(1) - h) * h); + return mix(mix(q1, q2, h), mix(s1, s2, h), static_cast(2) * (static_cast(1) - h) * h); } template @@ -52,7 +53,7 @@ namespace glm ) { detail::tquat invQuat = inverse(curr); - return exp((log(next + invQuat) + log(prev + invQuat)) / T(-4)) * curr; + return exp((log(next + invQuat) + log(prev + invQuat)) / static_cast(-4)) * curr; } template @@ -62,7 +63,10 @@ namespace glm ) { detail::tvec3 u(q.x, q.y, q.z); - float Angle = glm::length(u); + T Angle = glm::length(u); + if (Angle < epsilon()) + return detail::tquat(); + detail::tvec3 v(u / Angle); return detail::tquat(cos(Angle), sin(Angle) * v); } @@ -73,18 +77,20 @@ namespace glm detail::tquat const & q ) { - if((q.x == static_cast(0)) && (q.y == static_cast(0)) && (q.z == static_cast(0))) + detail::tvec3 u(q.x, q.y, q.z); + T Vec3Len = length(u); + + if (Vec3Len < epsilon()) { - if(q.w > T(0)) - return detail::tquat(log(q.w), T(0), T(0), T(0)); - else if(q.w < T(0)) - return detail::tquat(log(-q.w), T(3.1415926535897932384626433832795), T(0),T(0)); + if(q.w > static_cast(0)) + return detail::tquat(log(q.w), static_cast(0), static_cast(0), static_cast(0)); + else if(q.w < static_cast(0)) + return detail::tquat(log(-q.w), pi(), static_cast(0), static_cast(0)); else return detail::tquat(std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity()); } else { - T Vec3Len = sqrt(q.x * q.x + q.y * q.y + q.z * q.z); T QuatLen = sqrt(Vec3Len * Vec3Len + q.w * q.w); T t = atan(Vec3Len, T(q.w)) / Vec3Len; return detail::tquat(log(QuatLen), t * q.x, t * q.y, t * q.z); @@ -98,11 +104,11 @@ namespace glm T const & y ) { - if(abs(x.w) > T(0.9999)) + if(abs(x.w) > (static_cast(1) - epsilon())) return x; - float Angle = acos(y); - float NewAngle = Angle * y; - float Div = sin(NewAngle) / sin(Angle); + T Angle = acos(y); + T NewAngle = Angle * y; + T Div = sin(NewAngle) / sin(Angle); return detail::tquat( cos(NewAngle), x.x * Div, @@ -146,7 +152,7 @@ namespace glm detail::tquat const & q ) { - T w = static_cast(1.0) - q.x * q.x - q.y * q.y - q.z * q.z; + T w = static_cast(1) - q.x * q.x - q.y * q.y - q.z * q.z; if(w < T(0)) return T(0); else @@ -170,12 +176,12 @@ namespace glm T const & a ) { - if(a <= T(0)) return x; - if(a >= T(1)) return y; + if(a <= static_cast(0)) return x; + if(a >= static_cast(1)) return y; T fCos = dot(x, y); detail::tquat y2(y); //BUG!!! tquat y2; - if(fCos < T(0)) + if(fCos < static_cast(0)) { y2 = -y; fCos = -fCos; @@ -183,7 +189,7 @@ namespace glm //if(fCos > 1.0f) // problem T k0, k1; - if(fCos > T(0.9999)) + if(fCos > (static_cast(1) - epsilon())) { k0 = static_cast(1) - a; k1 = static_cast(0) + a; //BUG!!! 1.0f + a; @@ -193,8 +199,8 @@ namespace glm T fSin = sqrt(T(1) - fCos * fCos); T fAngle = atan(fSin, fCos); T fOneOverSin = static_cast(1) / fSin; - k0 = sin((T(1) - a) * fAngle) * fOneOverSin; - k1 = sin((T(0) + a) * fAngle) * fOneOverSin; + k0 = sin((static_cast(1) - a) * fAngle) * fOneOverSin; + k1 = sin((static_cast(0) + a) * fAngle) * fOneOverSin; } return detail::tquat( @@ -212,7 +218,7 @@ namespace glm T const & a ) { - return glm::normalize(x * (T(1) - a) + (y * a)); + return glm::normalize(x * (static_cast(1) - a) + (y * a)); } template @@ -225,7 +231,7 @@ namespace glm T cosTheta = dot(orig, dest); detail::tvec3 rotationAxis; - if(cosTheta < T(-1) + epsilon()) + if(cosTheta < static_cast(-1) + epsilon()) { // special case when vectors in opposite directions : // there is no "ideal" rotation axis @@ -243,11 +249,11 @@ namespace glm // Implementation from Stan Melax's Game Programming Gems 1 article rotationAxis = cross(orig, dest); - T s = sqrt((T(1) + cosTheta) * T(2)); + T s = sqrt((T(1) + cosTheta) * static_cast(2)); T invs = static_cast(1) / s; return detail::tquat( - s * T(0.5f), + s * static_cast(0.5f), rotationAxis.x * invs, rotationAxis.y * invs, rotationAxis.z * invs); diff --git a/readme.txt b/readme.txt index 5ce1f1c2..c00f7ec0 100644 --- a/readme.txt +++ b/readme.txt @@ -45,7 +45,7 @@ GLM 0.9.6.0: 2014-XX-XX - Added move contructors and assignment operators (#141) ================================================================================ -GLM 0.9.5.4: 2014-0X-XX +GLM 0.9.5.4: 2014-06-21 -------------------------------------------------------------------------------- - Fixed non-utf8 character #196 - Added FindGLM install for CMake #189 @@ -64,6 +64,7 @@ GLM 0.9.5.4: 2014-0X-XX - Fixed std::copy and std::vector with GLM types #214 - Fixed strict aliasing issues #212, #152 - Fixed std::nextafter not supported with C++11 on Android #213 +- Fixed corner cases in exp and log functions for quaternions #199 ================================================================================ GLM 0.9.5.3: 2014-04-02 diff --git a/test/core/core_func_matrix.cpp b/test/core/core_func_matrix.cpp index 1b609f32..5c95672c 100644 --- a/test/core/core_func_matrix.cpp +++ b/test/core/core_func_matrix.cpp @@ -228,10 +228,10 @@ int test_inverse_perf(std::size_t Instance, char const * Message) //glm::uint Ulp = 0; //Ulp = glm::max(glm::float_distance(*Dst, *Src), Ulp); - printf("inverse<%s>(%f): %d\n", Message, Diff, EndTime - StartTime); + printf("inverse<%s>(%f): %lu\n", Message, Diff, EndTime - StartTime); return 0; -}; +} int main() {