diff --git a/glm/core/func_exponential.inl b/glm/core/func_exponential.inl new file mode 100644 index 00000000..e8ff4cfe --- /dev/null +++ b/glm/core/func_exponential.inl @@ -0,0 +1,224 @@ +/////////////////////////////////////////////////////////////////////////////////// +/// OpenGL Mathematics (glm.g-truc.net) +/// +/// Copyright (c) 2005 - 2013 G-Truc Creation (www.g-truc.net) +/// Permission is hereby granted, free of charge, to any person obtaining a copy +/// of this software and associated documentation files (the "Software"), to deal +/// in the Software without restriction, including without limitation the rights +/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +/// copies of the Software, and to permit persons to whom the Software is +/// furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +/// THE SOFTWARE. +/// +/// @ref core +/// @file glm/core/func_exponential.inl +/// @date 2008-08-03 / 2011-06-15 +/// @author Christophe Riccio +/////////////////////////////////////////////////////////////////////////////////// + +#include "func_vector_relational.hpp" +#include "_vectorize.hpp" +#include +#include + +namespace glm +{ + // pow + template + GLM_FUNC_QUALIFIER genType pow + ( + genType const & x, + genType const & y + ) + { + GLM_STATIC_ASSERT( + std::numeric_limits::is_iec559, + "'pow' only accept floating-point inputs"); + + return std::pow(x, y); + } + + VECTORIZE_VEC_VEC(pow) + + // exp + template + GLM_FUNC_QUALIFIER genType exp + ( + genType const & x + ) + { + GLM_STATIC_ASSERT( + std::numeric_limits::is_iec559, + "'exp' only accept floating-point inputs"); + + return std::exp(x); + } + + VECTORIZE_VEC(exp) + + // log + template + GLM_FUNC_QUALIFIER genType log + ( + genType const & x + ) + { + GLM_STATIC_ASSERT( + std::numeric_limits::is_iec559, + "'log' only accept floating-point inputs"); + + return std::log(x); + } + + VECTORIZE_VEC(log) + + //exp2, ln2 = 0.69314718055994530941723212145818f + template + GLM_FUNC_QUALIFIER genType exp2 + ( + genType const & x + ) + { + GLM_STATIC_ASSERT( + std::numeric_limits::is_iec559, + "'exp2' only accept floating-point inputs"); + + return std::exp(static_cast(0.69314718055994530941723212145818) * x); + } + + VECTORIZE_VEC(exp2) + +namespace detail +{ + template + struct compute_log2 + { + template + T operator() (T const & Value) const; + }; + + template <> + struct compute_log2 + { + template + T operator() (T const & Value) const + { + return static_cast(::std::log(Value)) * static_cast(1.4426950408889634073599246810019); + } + }; + +}//namespace detail + + // log2, ln2 = 0.69314718055994530941723212145818f + template + GLM_FUNC_QUALIFIER genType log2 + ( + genType const & x + ) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || std::numeric_limits::is_integer, + "GLM core 'log2' only accept floating-point inputs. Include for additional integer support."); + + assert(x > genType(0)); // log2 is only defined on the range (0, inf] + return detail::compute_log2::is_iec559>()(x); + } + + VECTORIZE_VEC(log2) + + // sqrt + template + GLM_FUNC_QUALIFIER genType sqrt + ( + genType const & x + ) + { + GLM_STATIC_ASSERT( + std::numeric_limits::is_iec559, + "'sqrt' only accept floating-point inputs"); + + assert(x >= genType(0)); + + return std::sqrt(x); + } + + VECTORIZE_VEC(sqrt) + + template + GLM_FUNC_QUALIFIER genType inversesqrt + ( + genType const & x + ) + { + GLM_STATIC_ASSERT( + std::numeric_limits::is_iec559, + "'inversesqrt' only accept floating-point inputs"); + + assert(x > genType(0)); + + return genType(1) / std::sqrt(x); + } + + VECTORIZE_VEC(inversesqrt) + + namespace detail + { + template + genType fastInversesqrt(genType const & v) + { + genType tmp(v); + genType xhalf(tmp * genType(0.5f)); + genUType i = *reinterpret_cast(const_cast(&v)); + i = genUType(0x5f375a86) - (i >> genUType(1)); + // tmp = *reinterpret_cast(&i); + { + genType* ptr(reinterpret_cast(&i)); + tmp = *ptr; + } + tmp = tmp * (genType(1.5f) - xhalf * tmp * tmp); + return tmp; + } + } + + template <> + GLM_FUNC_QUALIFIER lowp_vec1 inversesqrt(lowp_vec1 const & v) + { + assert(glm::all(glm::greaterThan(v, lowp_vec1(0)))); + + return detail::fastInversesqrt(v); + } + + template <> + GLM_FUNC_QUALIFIER lowp_vec2 inversesqrt(lowp_vec2 const & v) + { + assert(glm::all(glm::greaterThan(v, lowp_vec2(0)))); + + return detail::fastInversesqrt(v); + } + + template <> + GLM_FUNC_QUALIFIER lowp_vec3 inversesqrt(lowp_vec3 const & v) + { + assert(glm::all(glm::greaterThan(v, lowp_vec3(0)))); + + return detail::fastInversesqrt(v); + } + + template <> + GLM_FUNC_QUALIFIER lowp_vec4 inversesqrt(lowp_vec4 const & v) + { + assert(glm::all(glm::greaterThan(v, lowp_vec4(0)))); + + return detail::fastInversesqrt(v); + } + +}//namespace glm diff --git a/glm/detail/func_packing.inl b/glm/detail/func_packing.inl index e5eb0933..60dfc63b 100644 --- a/glm/detail/func_packing.inl +++ b/glm/detail/func_packing.inl @@ -35,7 +35,9 @@ namespace glm GLM_FUNC_QUALIFIER uint packUnorm2x16(vec2 const & v) { u16vec2 Topack(round(clamp(v, 0.0f, 1.0f) * 65535.0f)); - return reinterpret_cast(Topack); + // return reinterpret_cast(Topack); + uint* ptr(reinterpret_cast(&Topack)); + return *ptr; } GLM_FUNC_QUALIFIER vec2 unpackUnorm2x16(uint const & p) @@ -47,7 +49,9 @@ namespace glm GLM_FUNC_QUALIFIER uint packSnorm2x16(vec2 const & v) { i16vec2 Topack(round(clamp(v ,-1.0f, 1.0f) * 32767.0f)); - return reinterpret_cast(Topack); + // return reinterpret_cast(Topack); + uint* ptr(reinterpret_cast(&Topack)); + return *ptr; } GLM_FUNC_QUALIFIER vec2 unpackSnorm2x16(uint const & p) diff --git a/glm/gtc/quaternion.hpp b/glm/gtc/quaternion.hpp index 44474573..1470a85d 100644 --- a/glm/gtc/quaternion.hpp +++ b/glm/gtc/quaternion.hpp @@ -59,6 +59,7 @@ namespace detail { enum ctor{null}; + typedef T value_type; typedef tvec4 bool_type; public: diff --git a/glm/gtx/bit.inl b/glm/gtx/bit.inl index e8ef509f..f34a9833 100644 --- a/glm/gtx/bit.inl +++ b/glm/gtx/bit.inl @@ -287,7 +287,7 @@ namespace glm assert(ToBit <= sizeof(genIUType) * std::size_t(8)); genIUType Result = Value; - for(std::size_t i = 0; i <= ToBit; ++i) + for(signed i = 0; i <= ToBit; ++i) Result |= (1 << i); return Result; } @@ -304,7 +304,7 @@ namespace glm assert(ToBit <= sizeof(genIUType) * std::size_t(8)); genIUType Result = Value; - for(std::size_t i = 0; i <= ToBit; ++i) + for(signed i = 0; i <= ToBit; ++i) Result &= ~(1 << i); return Result; } diff --git a/glm/gtx/io.hpp b/glm/gtx/io.hpp index e97d27fb..25e9d74b 100644 --- a/glm/gtx/io.hpp +++ b/glm/gtx/io.hpp @@ -1,7 +1,7 @@ /////////////////////////////////////////////////////////////////////////////////// /// OpenGL Mathematics (glm.g-truc.net) /// -/// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net) +/// Copyright (c) 2005 - 2013 G-Truc Creation (www.g-truc.net) /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal /// in the Software without restriction, including without limitation the rights @@ -26,94 +26,174 @@ /// @author Jan P Springer (regnirpsj@gmail.com) /// /// @see core (dependence) -/// @see gtx_quaternion (dependence) +/// @see gtc_quaternion (dependence) /// /// @defgroup gtx_io GLM_GTX_io /// @ingroup gtx /// /// @brief std::[w]ostream support for glm types /// +/// std::[w]ostream support for glm types + precision/width/etc. manipulators +/// based on howard hinnant's std::chrono io proposal +/// [http://home.roadrunner.com/~hinnant/bloomington/chrono_io.html] +/// /// needs to be included to use these functionalities. /////////////////////////////////////////////////////////////////////////////////// #ifndef GLM_GTX_io -#define GLM_GTX_io +#define GLM_GTX_io GLM_VERSION // Dependency: -#include "../detail/setup.hpp" -#include "../gtc/quaternion.hpp" +#include "../glm.hpp" +#include "../gtx/quaternion.hpp" -#if(defined(GLM_MESSAGES) && !defined(GLM_EXT_INCLUDED)) -# pragma message("GLM: GLM_GTX_io extension included") +#if(defined(GLM_MESSAGES) && !defined(glm_ext)) +# pragma message("GLM: GLM_GTX_io extension included") #endif #include // std::basic_ostream<> (fwd) +#include // std::locale, std::locale::facet, std::locale::id #include // std::pair<> namespace glm { - /// @addtogroup gtx_io - /// @{ + /// @addtogroup gtx_io + /// @{ namespace io { - class precision_guard { + enum order_type { column_major, row_major, }; + + template + class format_punct : public std::locale::facet { - public: + typedef CTy char_type; - GLM_FUNC_DECL explicit precision_guard(); - GLM_FUNC_DECL ~precision_guard(); - - private: + public: - unsigned precision_; - unsigned value_width_; + static std::locale::id id; + + 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&); }; - class format_guard - { - public: - enum order_t { column_major, row_major, }; + template > + class basic_state_saver { - GLM_FUNC_DECL explicit format_guard(); - GLM_FUNC_DECL ~format_guard(); + public: - private: + explicit basic_state_saver(std::basic_ios&); + ~basic_state_saver(); - order_t order_; - char cr_; - }; + private: - // decimal places (dflt: 3) - GLM_FUNC_DECL unsigned& precision(); + 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&); + + }; - // sign + value + '.' + decimals (dflt: 1 + 4 + 1 + precision()) - GLM_FUNC_DECL unsigned& value_width(); + typedef basic_state_saver state_saver; + typedef basic_state_saver wstate_saver; + + template > + class basic_format_saver { - // matrix output order (dflt: row_major) - GLM_FUNC_DECL format_guard::order_t& order(); + public: - // carriage/return char (dflt: '\n') - GLM_FUNC_DECL char& cr(); + explicit basic_format_saver(std::basic_ios&); + ~basic_format_saver(); - // matrix output order -> column_major - GLM_FUNC_DECL std::ios_base& column_major(std::ios_base&); + private: - // matrix output order -> row_major - GLM_FUNC_DECL std::ios_base& row_major (std::ios_base&); + basic_state_saver const bss_; - // carriage/return char -> '\n' - GLM_FUNC_DECL std::ios_base& formatted (std::ios_base&); + basic_format_saver& operator=(basic_format_saver const&); + + }; - // carriage/return char -> ' ' - GLM_FUNC_DECL std::ios_base& unformatted (std::ios_base&); + typedef basic_format_saver format_saver; + typedef basic_format_saver wformat_saver; + + struct precision { + unsigned value; + + explicit precision(unsigned); + + }; + + struct width { + + unsigned value; + + explicit width(unsigned); + + }; + + 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 @@ -140,9 +220,15 @@ namespace glm 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&); - - /// @} -}//namespace detail + + 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 2329ffd8..3132a88e 100644 --- a/glm/gtx/io.inl +++ b/glm/gtx/io.inl @@ -1,328 +1,579 @@ /////////////////////////////////////////////////////////////////////////////////////////////////// -// OpenGL Mathematics Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net) +// OpenGL Mathematics Copyright (c) 2005 - 2013 G-Truc Creation (www.g-truc.net) /////////////////////////////////////////////////////////////////////////////////////////////////// // Created : 2013-11-22 -// Updated : 2013-11-22 +// Updated : 2013-12-18 // Licence : This source is under MIT License // File : glm/gtx/inl.inl /////////////////////////////////////////////////////////////////////////////////////////////////// -#include "../matrix.hpp" -// #include // boost::io::ios_all_saver -#include // std::setfill<>, std::fixed, std::setprecision, std::right, - // std::setw -#include // std::basic_ostream<> +#include // std::setfill<>, std::fixed, std::setprecision, std::right, std::setw +#include // std::basic_ostream<> -namespace glm{ -namespace io +namespace glm { + namespace io + { + template /* explicit */ GLM_FUNC_QUALIFIER - precision_guard::precision_guard() - : precision_ (precision()), - value_width_(value_width()) + 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 - precision_guard::~precision_guard() + basic_state_saver::~basic_state_saver() { - value_width() = value_width_; - precision() = precision_; + 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 - format_guard::format_guard() - : order_(order()), - cr_ (cr()) + order::order(order_type a) + : value(a) {} - - GLM_FUNC_QUALIFIER - format_guard::~format_guard() - { - cr() = cr_; - order() = order_; - } - - GLM_FUNC_QUALIFIER unsigned& precision() - { - static unsigned p(3); - - return p; - } - GLM_FUNC_QUALIFIER unsigned& value_width() + template + GLM_FUNC_QUALIFIER FTy const& + get_facet(std::basic_ios& ios) { - static unsigned p(9); - - return p; - } - - GLM_FUNC_QUALIFIER format_guard::order_t& order() - { - static format_guard::order_t p(format_guard::row_major); - - return p; - } - - GLM_FUNC_QUALIFIER char& - cr() - { - static char p('\n'); return p; - } - - GLM_FUNC_QUALIFIER std::ios_base& column_major(std::ios_base& os) - { - order() = format_guard::column_major; - - return os; - } - - GLM_FUNC_QUALIFIER std::ios_base& row_major(std::ios_base& os) - { - order() = format_guard::row_major; - - return os; - } - - GLM_FUNC_QUALIFIER std::ios_base& formatted(std::ios_base& os) - { - cr() = '\n'; - - return os; - } - - GLM_FUNC_QUALIFIER std::ios_base& unformatted(std::ios_base& os) - { - cr() = ' '; - - return os; - } - -} // namespace io -namespace detail -{ - // functions, inlined (inline) - - 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) { - // boost::io::ios_all_saver const ias(os); - - os << std::fixed << std::setprecision(io::precision()) - << '[' - << std::right << std::setfill(' ') << std::setw(io::value_width()) << a.w << ',' - << std::right << std::setfill(' ') << std::setw(io::value_width()) << a.x << ',' - << std::right << std::setfill(' ') << std::setw(io::value_width()) << a.y << ',' - << std::right << std::setfill(' ') << std::setw(io::value_width()) << a.z - << ']'; + 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; } - 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) { - // boost::io::ios_all_saver const ias(os); - - os << std::fixed << std::setprecision(io::precision()) - << '[' - << std::right << std::setfill(' ') << std::setw(io::value_width()) << a.x << ',' - << std::right << std::setfill(' ') << std::setw(io::value_width()) << a.y - << ']'; - } - - return os; - } + } // namespace io + namespace detail { + template - GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tvec3 const& a) + GLM_FUNC_QUALIFIER std::basic_ostream& + operator<<(std::basic_ostream& os, tquat const& a) { typename std::basic_ostream::sentry const cerberus(os); if (cerberus) { - // boost::io::ios_all_saver const ias(os); - - os << std::fixed << std::setprecision(io::precision()) - << '[' - << std::right << std::setfill(' ') << std::setw(io::value_width()) << a.x << ',' - << std::right << std::setfill(' ') << std::setw(io::value_width()) << a.y << ',' - << std::right << std::setfill(' ') << std::setw(io::value_width()) << a.z - << ']'; - } + io::format_punct const& fmt(io::get_facet >(os)); - 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) { - // boost::io::ios_all_saver const ias(os); - - os << std::fixed << std::setprecision(io::precision()) - << '[' - << std::right << std::setfill(' ') << std::setw(io::value_width()) << a.x << ',' - << std::right << std::setfill(' ') << std::setw(io::value_width()) << a.y << ',' - << std::right << std::setfill(' ') << std::setw(io::value_width()) << a.z << ',' - << std::right << std::setfill(' ') << std::setw(io::value_width()) << a.w - << ']'; - } - - return os; - } - - template - GLM_FUNC_QUALIFIER std::basic_ostream& operator<<(std::basic_ostream& os, tmat2x2 const& m) - { - typename std::basic_ostream::sentry const cerberus(os); - - if (cerberus) { + if (fmt.formatted) { + io::basic_state_saver const bss(os); - os << io::cr() - << '[' << m[0] << io::cr() - << ' ' << m[1] << ']'; + 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& m) + 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); - os << io::cr() - << '[' << m[0] << io::cr() - << ' ' << m[1] << ']'; + 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& m) + 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); - os << io::cr() - << '[' << m[0] << io::cr() - << ' ' << m[1] << ']'; + 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& m) + 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); - os << io::cr() - << '[' << m[0] << io::cr() - << ' ' << m[1] << io::cr() - << ' ' << m[2] << ']'; + 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& m) + 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); - os << io::cr() - << '[' << m[0] << io::cr() - << ' ' << m[1] << io::cr() - << ' ' << m[2] << ']'; + 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& m) + 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); - os << io::cr() - << '[' << m[0] << io::cr() - << ' ' << m[1] << io::cr() - << ' ' << m[2] << ']'; + 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& m) + 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); - os << io::cr() - << '[' << m[0] << io::cr() - << ' ' << m[1] << io::cr() - << ' ' << m[2] << io::cr() - << ' ' << m[3] << ']'; + 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& m) + 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); - os << io::cr() - << '[' << m[0] << io::cr() - << ' ' << m[1] << io::cr() - << ' ' << m[2] << io::cr() - << ' ' << m[3] << ']'; + 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& m) + 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); - os << io::cr() - << '[' << m[0] << io::cr() - << ' ' << m[1] << io::cr() - << ' ' << m[2] << io::cr() - << ' ' << m[3] << ']'; + 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; } -}//namespace detail + 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/test/gtx/gtx_io.cpp b/test/gtx/gtx_io.cpp index 05ba8e9b..6fcaa60e 100644 --- a/test/gtx/gtx_io.cpp +++ b/test/gtx/gtx_io.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include namespace { @@ -32,8 +33,60 @@ namespace { return os; } + template + std::basic_string + type_name(std::basic_ostream& os, T const&) + { + std::basic_ostringstream ostr; + + if (typeid(T) == typeid(glm::detail::tquat)) { ostr << "quat"; } + else if (typeid(T) == typeid(glm::detail::tvec2)) { ostr << "vec2"; } + else if (typeid(T) == typeid(glm::detail::tvec3)) { ostr << "vec3"; } + else if (typeid(T) == typeid(glm::detail::tvec4)) { ostr << "vec4"; } + else if (typeid(T) == typeid(glm::detail::tmat2x2)) { ostr << "mat2x2"; } + else if (typeid(T) == typeid(glm::detail::tmat2x3)) { ostr << "mat2x3"; } + else if (typeid(T) == typeid(glm::detail::tmat2x4)) { ostr << "mat2x4"; } + else if (typeid(T) == typeid(glm::detail::tmat3x2)) { ostr << "mat3x2"; } + else if (typeid(T) == typeid(glm::detail::tmat3x3)) { ostr << "mat3x3"; } + else if (typeid(T) == typeid(glm::detail::tmat3x4)) { ostr << "mat3x4"; } + else if (typeid(T) == typeid(glm::detail::tmat4x2)) { ostr << "mat4x2"; } + else if (typeid(T) == typeid(glm::detail::tmat4x3)) { ostr << "mat4x3"; } + else if (typeid(T) == typeid(glm::detail::tmat4x4)) { ostr << "mat4x4"; } + else { ostr << "unknown"; } + + ostr << '<' << typeid(U).name() << ',' << P << '>'; + + return ostr.str(); + } + } // namespace { +template +int test_io_quat(OS& os) +{ + os << '\n' + << typeid(OS).name() + << '\n'; + + glm::detail::tquat const q(1, 0, 0, 0); + + { + glm::io::basic_format_saver const iofs(os); + + os << glm::io::precision(2) << glm::io::width(1 + 2 + 1 + 2) + << type_name(os, q) << ": " << q << '\n'; + } + + { + glm::io::basic_format_saver const iofs(os); + + os << glm::io::unformatted + << type_name(os, q) << ": " << q << '\n'; + } + + return 0; +} + template int test_io_vec(OS& os) { @@ -45,18 +98,16 @@ int test_io_vec(OS& os) glm::detail::tvec3 const v3(2, 3, 4); glm::detail::tvec4 const v4(5, 6, 7, 8); - os << "vec2<" << typeid(T).name() << ',' << P << ">: " << v2 << '\n' - << "vec3<" << typeid(T).name() << ',' << P << ">: " << v3 << '\n' - << "vec4<" << typeid(T).name() << ',' << P << ">: " << v4 << '\n'; + os << type_name(os, v2) << ": " << v2 << '\n' + << type_name(os, v3) << ": " << v3 << '\n' + << type_name(os, v4) << ": " << v4 << '\n'; - glm::io::precision_guard const iopg; + glm::io::basic_format_saver const iofs(os); - glm::io::precision() = 2; - glm::io::value_width() = 1 + 2 + 1 + glm::io::precision(); - - os << "vec2<" << typeid(T).name() << ',' << P << ">: " << v2 << '\n' - << "vec3<" << typeid(T).name() << ',' << P << ">: " << v3 << '\n' - << "vec4<" << typeid(T).name() << ',' << P << ">: " << v4 << '\n'; + os << glm::io::precision(2) << glm::io::width(1 + 2 + 1 + 2) + << type_name(os, v2) << ": " << v2 << '\n' + << type_name(os, v3) << ": " << v3 << '\n' + << type_name(os, v4) << ": " << v4 << '\n'; return 0; } @@ -93,12 +144,10 @@ int test_io_mat(OS& os) << "mat4x4<" << typeid(T).name() << ',' << P << ">: " << glm::detail::tmat4x4(v4_1, v4_2, v4_3, v4_4) << '\n'; #endif - glm::io::precision_guard const iopg; + glm::io::basic_format_saver const iofs(os); - glm::io::precision() = 2; - glm::io::value_width() = 1 + 2 + 1 + glm::io::precision(); - - os << "mat2x2<" << typeid(T).name() << ',' << P << ">: " << glm::detail::tmat2x2(v2_1, v2_2) << '\n' + os << glm::io::precision(2) << glm::io::width(1 + 2 + 1 + 2) + << "mat2x2<" << typeid(T).name() << ',' << P << ">: " << glm::detail::tmat2x2(v2_1, v2_2) << '\n' << "mat2x3<" << typeid(T).name() << ',' << P << ">: " << glm::detail::tmat2x3(v3_1, v3_2) << '\n' << "mat2x4<" << typeid(T).name() << ',' << P << ">: " << glm::detail::tmat2x4(v4_1, v4_2) << '\n' << "mat3x2<" << typeid(T).name() << ',' << P << ">: " << glm::detail::tmat3x2(v2_1, v2_2, v2_3) << '\n' @@ -108,7 +157,8 @@ int test_io_mat(OS& os) << "mat4x3<" << typeid(T).name() << ',' << P << ">: " << glm::detail::tmat4x3(v3_1, v3_2, v3_3, v3_4) << '\n' << "mat4x4<" << typeid(T).name() << ',' << P << ">: " << glm::detail::tmat4x4(v4_1, v4_2, v4_3, v4_4) << '\n'; - os << glm::io::column_major + os << glm::io::unformatted + << glm::io::order(glm::io::column_major) << "mat2x2<" << typeid(T).name() << ',' << P << ">: " << glm::detail::tmat2x2(v2_1, v2_2) << '\n' << "mat2x3<" << typeid(T).name() << ',' << P << ">: " << glm::detail::tmat2x3(v3_1, v3_2) << '\n' << "mat2x4<" << typeid(T).name() << ',' << P << ">: " << glm::detail::tmat2x4(v4_1, v4_2) << '\n' @@ -126,6 +176,13 @@ int main() { int Error(0); + Error += test_io_quat(std::cout); + Error += test_io_quat(std::wcout); + Error += test_io_quat(std::cout); + Error += test_io_quat(std::wcout); + Error += test_io_quat(std::cout); + Error += test_io_quat(std::wcout); + Error += test_io_vec(std::cout); Error += test_io_vec(std::wcout); Error += test_io_vec(std::cout);