summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/qvm
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/qvm')
-rw-r--r--src/boost/libs/qvm/README.md12
-rw-r--r--src/boost/libs/qvm/gen/Jamfile.v28
-rw-r--r--src/boost/libs/qvm/gen/gen.cpp1909
-rw-r--r--src/boost/libs/qvm/index.html11
-rw-r--r--src/boost/libs/qvm/meta/libraries.json17
-rw-r--r--src/boost/libs/qvm/test/Jamfile.v2176
-rw-r--r--src/boost/libs/qvm/test/access_m_fail1.cpp36
-rw-r--r--src/boost/libs/qvm/test/access_m_fail2.cpp36
-rw-r--r--src/boost/libs/qvm/test/access_m_test.cpp126
-rw-r--r--src/boost/libs/qvm/test/access_q_fail.cpp35
-rw-r--r--src/boost/libs/qvm/test/access_q_test.cpp39
-rw-r--r--src/boost/libs/qvm/test/access_v_fail1.cpp35
-rw-r--r--src/boost/libs/qvm/test/access_v_fail2.cpp35
-rw-r--r--src/boost/libs/qvm/test/access_v_test.cpp40
-rw-r--r--src/boost/libs/qvm/test/assign_test.cpp70
-rw-r--r--src/boost/libs/qvm/test/cmp_mm_test.cpp107
-rw-r--r--src/boost/libs/qvm/test/cmp_qq_test.cpp35
-rw-r--r--src/boost/libs/qvm/test/cmp_vv_test.cpp94
-rw-r--r--src/boost/libs/qvm/test/col_mat_test.cpp40
-rw-r--r--src/boost/libs/qvm/test/col_test.cpp118
-rw-r--r--src/boost/libs/qvm/test/conjugate_test.cpp41
-rw-r--r--src/boost/libs/qvm/test/convert_to_test.cpp86
-rw-r--r--src/boost/libs/qvm/test/cross_test.cpp56
-rw-r--r--src/boost/libs/qvm/test/deduce_matrix_test.cpp51
-rw-r--r--src/boost/libs/qvm/test/deduce_scalar_fail1.cpp8
-rw-r--r--src/boost/libs/qvm/test/deduce_scalar_fail2.cpp9
-rw-r--r--src/boost/libs/qvm/test/deduce_scalar_fail3.cpp10
-rw-r--r--src/boost/libs/qvm/test/deduce_scalar_test.cpp77
-rw-r--r--src/boost/libs/qvm/test/deduce_vector_test.cpp50
-rw-r--r--src/boost/libs/qvm/test/del_col_test.cpp61
-rw-r--r--src/boost/libs/qvm/test/del_row_col_test.cpp101
-rw-r--r--src/boost/libs/qvm/test/del_row_test.cpp61
-rw-r--r--src/boost/libs/qvm/test/determinant_test.cpp32
-rw-r--r--src/boost/libs/qvm/test/diag_mat_test.cpp42
-rw-r--r--src/boost/libs/qvm/test/diag_test.cpp65
-rw-r--r--src/boost/libs/qvm/test/div_eq_ms_test.cpp40
-rw-r--r--src/boost/libs/qvm/test/div_eq_qs_test.cpp28
-rw-r--r--src/boost/libs/qvm/test/div_eq_vs_test.cpp33
-rw-r--r--src/boost/libs/qvm/test/div_ms_test.cpp52
-rw-r--r--src/boost/libs/qvm/test/div_qs_test.cpp40
-rw-r--r--src/boost/libs/qvm/test/div_vs_test.cpp45
-rw-r--r--src/boost/libs/qvm/test/dot_qq_test.cpp44
-rw-r--r--src/boost/libs/qvm/test/dot_vv_test.cpp48
-rw-r--r--src/boost/libs/qvm/test/eq_mm_test.cpp53
-rw-r--r--src/boost/libs/qvm/test/eq_qq_test.cpp40
-rw-r--r--src/boost/libs/qvm/test/eq_vv_test.cpp44
-rw-r--r--src/boost/libs/qvm/test/gold.hpp439
-rw-r--r--src/boost/libs/qvm/test/header-test.cpp7
-rw-r--r--src/boost/libs/qvm/test/identity_mat_test.cpp36
-rw-r--r--src/boost/libs/qvm/test/identity_quat_test.cpp34
-rw-r--r--src/boost/libs/qvm/test/interop_test.cpp435
-rw-r--r--src/boost/libs/qvm/test/inverse_m_test.cpp55
-rw-r--r--src/boost/libs/qvm/test/inverse_q_test.cpp41
-rw-r--r--src/boost/libs/qvm/test/mag_q_test.cpp31
-rw-r--r--src/boost/libs/qvm/test/mag_sqr_q_test.cpp30
-rw-r--r--src/boost/libs/qvm/test/mag_sqr_v_test.cpp35
-rw-r--r--src/boost/libs/qvm/test/mag_v_test.cpp35
-rw-r--r--src/boost/libs/qvm/test/mat_index_test.cpp34
-rw-r--r--src/boost/libs/qvm/test/mat_traits_array_test.cpp136
-rw-r--r--src/boost/libs/qvm/test/math_test.cpp102
-rw-r--r--src/boost/libs/qvm/test/minus_eq_mm_test.cpp49
-rw-r--r--src/boost/libs/qvm/test/minus_eq_qq_test.cpp37
-rw-r--r--src/boost/libs/qvm/test/minus_eq_vv_test.cpp41
-rw-r--r--src/boost/libs/qvm/test/minus_m_test.cpp52
-rw-r--r--src/boost/libs/qvm/test/minus_mm_test.cpp61
-rw-r--r--src/boost/libs/qvm/test/minus_q_test.cpp40
-rw-r--r--src/boost/libs/qvm/test/minus_qq_test.cpp49
-rw-r--r--src/boost/libs/qvm/test/minus_v_test.cpp44
-rw-r--r--src/boost/libs/qvm/test/minus_vv_test.cpp53
-rw-r--r--src/boost/libs/qvm/test/mul_eq_mm_test.cpp42
-rw-r--r--src/boost/libs/qvm/test/mul_eq_ms_test.cpp40
-rw-r--r--src/boost/libs/qvm/test/mul_eq_qq_test.cpp46
-rw-r--r--src/boost/libs/qvm/test/mul_eq_qs_test.cpp28
-rw-r--r--src/boost/libs/qvm/test/mul_eq_vs_test.cpp33
-rw-r--r--src/boost/libs/qvm/test/mul_mm_test.cpp55
-rw-r--r--src/boost/libs/qvm/test/mul_ms_test.cpp52
-rw-r--r--src/boost/libs/qvm/test/mul_mv_test.cpp75
-rw-r--r--src/boost/libs/qvm/test/mul_qq_test.cpp45
-rw-r--r--src/boost/libs/qvm/test/mul_qs_test.cpp40
-rw-r--r--src/boost/libs/qvm/test/mul_qv_test.cpp51
-rw-r--r--src/boost/libs/qvm/test/mul_sm_test.cpp52
-rw-r--r--src/boost/libs/qvm/test/mul_sv_test.cpp45
-rw-r--r--src/boost/libs/qvm/test/mul_vm_test.cpp75
-rw-r--r--src/boost/libs/qvm/test/mul_vs_test.cpp45
-rw-r--r--src/boost/libs/qvm/test/neg_col_test.cpp55
-rw-r--r--src/boost/libs/qvm/test/neg_row_test.cpp55
-rw-r--r--src/boost/libs/qvm/test/normalize_q_test.cpp51
-rw-r--r--src/boost/libs/qvm/test/normalize_v_test.cpp47
-rw-r--r--src/boost/libs/qvm/test/plus_eq_mm_test.cpp49
-rw-r--r--src/boost/libs/qvm/test/plus_eq_qq_test.cpp37
-rw-r--r--src/boost/libs/qvm/test/plus_eq_vv_test.cpp41
-rw-r--r--src/boost/libs/qvm/test/plus_mm_test.cpp61
-rw-r--r--src/boost/libs/qvm/test/plus_qq_test.cpp49
-rw-r--r--src/boost/libs/qvm/test/plus_vv_test.cpp53
-rw-r--r--src/boost/libs/qvm/test/projection_test.cpp39
-rw-r--r--src/boost/libs/qvm/test/quat_traits_array_test.cpp92
-rw-r--r--src/boost/libs/qvm/test/rot_mat_test.cpp433
-rw-r--r--src/boost/libs/qvm/test/rot_quat_test.cpp95
-rw-r--r--src/boost/libs/qvm/test/rotx_mat_test.cpp44
-rw-r--r--src/boost/libs/qvm/test/rotx_quat_test.cpp45
-rw-r--r--src/boost/libs/qvm/test/roty_mat_test.cpp44
-rw-r--r--src/boost/libs/qvm/test/roty_quat_test.cpp45
-rw-r--r--src/boost/libs/qvm/test/rotz_mat_test.cpp45
-rw-r--r--src/boost/libs/qvm/test/rotz_quat_test.cpp45
-rw-r--r--src/boost/libs/qvm/test/row_mat_test.cpp40
-rw-r--r--src/boost/libs/qvm/test/row_test.cpp118
-rw-r--r--src/boost/libs/qvm/test/scalar_cast_m_test.cpp34
-rw-r--r--src/boost/libs/qvm/test/scalar_cast_q_test.cpp30
-rw-r--r--src/boost/libs/qvm/test/scalar_cast_v_test.cpp31
-rw-r--r--src/boost/libs/qvm/test/scalar_traits_test.cpp35
-rw-r--r--src/boost/libs/qvm/test/slerp_test.cpp57
-rw-r--r--src/boost/libs/qvm/test/swap_cols_test.cpp101
-rw-r--r--src/boost/libs/qvm/test/swap_rows_test.cpp101
-rw-r--r--src/boost/libs/qvm/test/swizzle2_test.cpp104
-rw-r--r--src/boost/libs/qvm/test/swizzle2_test2.cpp49
-rw-r--r--src/boost/libs/qvm/test/swizzle2_test3.cpp49
-rw-r--r--src/boost/libs/qvm/test/swizzle2_test4.cpp49
-rw-r--r--src/boost/libs/qvm/test/swizzle3_test.cpp147
-rw-r--r--src/boost/libs/qvm/test/swizzle3_test2.cpp49
-rw-r--r--src/boost/libs/qvm/test/swizzle3_test3.cpp49
-rw-r--r--src/boost/libs/qvm/test/swizzle3_test4.cpp49
-rw-r--r--src/boost/libs/qvm/test/swizzle4_test.cpp219
-rw-r--r--src/boost/libs/qvm/test/swizzle4_test2.cpp49
-rw-r--r--src/boost/libs/qvm/test/swizzle4_test3.cpp49
-rw-r--r--src/boost/libs/qvm/test/swizzle4_test4.cpp49
-rw-r--r--src/boost/libs/qvm/test/swizzle_const_fail.cpp18
-rw-r--r--src/boost/libs/qvm/test/test_qvm.hpp257
-rw-r--r--src/boost/libs/qvm/test/test_qvm_matrix.hpp85
-rw-r--r--src/boost/libs/qvm/test/test_qvm_quaternion.hpp80
-rw-r--r--src/boost/libs/qvm/test/test_qvm_vector.hpp82
-rw-r--r--src/boost/libs/qvm/test/to_string_test.cpp67
-rw-r--r--src/boost/libs/qvm/test/transform_test.cpp43
-rw-r--r--src/boost/libs/qvm/test/translation_mat_test.cpp42
-rw-r--r--src/boost/libs/qvm/test/translation_test.cpp41
-rw-r--r--src/boost/libs/qvm/test/transpose_test.cpp52
-rw-r--r--src/boost/libs/qvm/test/vec_index_test.cpp28
-rw-r--r--src/boost/libs/qvm/test/vec_register_test.cpp225
-rw-r--r--src/boost/libs/qvm/test/vec_traits_array_test.cpp83
-rw-r--r--src/boost/libs/qvm/test/zero_mat_test.cpp78
-rw-r--r--src/boost/libs/qvm/test/zero_quat_test.cpp30
-rw-r--r--src/boost/libs/qvm/test/zero_vec_test.cpp53
141 files changed, 10943 insertions, 0 deletions
diff --git a/src/boost/libs/qvm/README.md b/src/boost/libs/qvm/README.md
new file mode 100644
index 000000000..40185be4e
--- /dev/null
+++ b/src/boost/libs/qvm/README.md
@@ -0,0 +1,12 @@
+QVM: Generic C++ library for working with Quaternions, Vectors and Matrices
+
+Official documentation: https://boostorg.github.io/qvm/
+
+* Emphasis on 2, 3 and 4-dimensional operations needed in graphics, video games and simulation applications.
+* Free function templates operate on any compatible user-defined quaternion, vector or matrix type.
+* Quaternion, vector and matrix types from different libraries or subsystems can be safely mixed in the same expression.
+* Type-safe mapping between compatible lvalue types with no temporary objects; e.g. transpose remaps the elements, rather than transforming the matrix.
+
+Copyright (c) 2018 Emil Dotchevski. Distributed under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt).
+
+Please post questions and feedback on the Boost Developers Mailing List.
diff --git a/src/boost/libs/qvm/gen/Jamfile.v2 b/src/boost/libs/qvm/gen/Jamfile.v2
new file mode 100644
index 000000000..2488eab4e
--- /dev/null
+++ b/src/boost/libs/qvm/gen/Jamfile.v2
@@ -0,0 +1,8 @@
+# Copyright (c) 2008-2009 Emil Dotchevski and Reverge Studios, Inc.
+
+# Distributed under the Boost Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+import testing ;
+
+run gen.cpp : -od ../include/boost/qvm/gen ;
diff --git a/src/boost/libs/qvm/gen/gen.cpp b/src/boost/libs/qvm/gen/gen.cpp
new file mode 100644
index 000000000..69c39a304
--- /dev/null
+++ b/src/boost/libs/qvm/gen/gen.cpp
@@ -0,0 +1,1909 @@
+//Copyright (c) 2008-2017 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include "boost/throw_exception.hpp"
+#include "boost/exception/info.hpp"
+#include "boost/exception/diagnostic_information.hpp"
+#include "boost/bind.hpp"
+#include <string>
+#include <map>
+#include <vector>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <set>
+#include <algorithm>
+#include <limits>
+#include <assert.h>
+
+#define NL "\n"
+#define TAB " "
+#define TAB1 TAB
+#define TAB2 TAB TAB
+#define TAB3 TAB TAB TAB
+#define TAB4 TAB TAB TAB TAB
+#define TAB5 TAB TAB TAB TAB TAB
+#define INCLUDE_MAT_ASSIGN "boost/qvm/gen/mat_assign%d.hpp"
+#define INCLUDE_VEC_ASSIGN "boost/qvm/gen/vec_assign%d.hpp"
+#define INCLUDE_STATIC_ASSERT "boost/qvm/static_assert.hpp"
+#define INCLUDE_MATH "boost/qvm/math.hpp"
+#define INCLUDE_THROW_EXCEPTION "boost/qvm/throw_exception.hpp"
+#define INCLUDE_ERROR "boost/qvm/error.hpp"
+#define INCLUDE_INLINE "boost/qvm/inline.hpp"
+#define INCLUDE_M_TRAITS "boost/qvm/mat_traits.hpp"
+#define INCLUDE_V_TRAITS "boost/qvm/vec_traits.hpp"
+#define INCLUDE_Q_TRAITS "boost/qvm/quat_traits.hpp"
+#define INCLUDE_S_TRAITS "boost/qvm/scalar_traits.hpp"
+#define INCLUDE_DEDUCE_M "boost/qvm/deduce_mat.hpp"
+#define INCLUDE_DEDUCE_V "boost/qvm/deduce_vec.hpp"
+#define INCLUDE_DEDUCE_Q "boost/qvm/deduce_quat.hpp"
+#define INCLUDE_DEDUCE_S "boost/qvm/deduce_scalar.hpp"
+#define INCLUDE_SWIZZLE_TRAITS "boost/qvm/detail/swizzle_traits.hpp"
+#define INCLUDE_ENABLE_IF "boost/qvm/enable_if.hpp"
+#define INCLUDE_ASSERT "boost/qvm/assert.hpp"
+
+namespace
+ {
+ struct exception_base: virtual std::exception, virtual boost::exception { };
+ struct bad_command_line: virtual exception_base { };
+ typedef boost::error_info<struct cmd_arg_,std::string> cmd_arg;
+
+ struct
+ null_deleter
+ {
+ template <class T>
+ void
+ operator()( T * ) const
+ {
+ }
+ };
+
+ std::string
+ get_include_guard()
+ {
+ std::ostringstream s;
+ s << std::setw(2) << std::setfill('0') << std::hex << std::uppercase;
+ s<<"BOOST_QVM_";
+ for( int i=0; i!=16; ++i )
+ s<<(rand()%256);
+ return s.str();
+ }
+
+ template <class T>
+ std::string
+ to_string( T const & x )
+ {
+ std::ostringstream s;
+ s<<x;
+ return s.str();
+ }
+
+ struct
+ command_line_options
+ {
+ bool con;
+ std::string output_directory;
+
+ command_line_options():
+ con(false)
+ {
+ }
+ };
+
+ class
+ output_file
+ {
+ output_file( output_file const & );
+ output_file & operator=( output_file const & );
+
+ std::string const output_directory;
+ bool const con;
+ std::ostringstream out_;
+ std::set<std::string> includes_;
+
+ public:
+
+ explicit
+ output_file( command_line_options const & opt ):
+ output_directory(opt.output_directory),
+ con(opt.con)
+ {
+ }
+
+ void
+ require_include( std::string const & fn )
+ {
+ assert(!strchr(fn.c_str(),'%'));
+ includes_.insert(fn);
+ };
+
+ std::ostream &
+ stream()
+ {
+ return out_;
+ }
+
+ void
+ dump( std::string const & name ) const
+ {
+ std::ostream * out = &std::cout;
+ boost::shared_ptr<std::ofstream> f;
+ if( !con )
+ {
+ std::string path;
+ if( !output_directory.empty() )
+ {
+ path+=output_directory;
+ path+='/';
+ path+=name;
+ }
+ boost::shared_ptr<std::ofstream>(new std::ofstream(path.c_str())).swap(f);
+ out = f.get();
+ std::cout << "Writing " << path << "..." << std::endl;
+ }
+ out->exceptions(std::ofstream::eofbit|std::ofstream::failbit|std::ofstream::badbit);
+ std::string include_guard=get_include_guard();
+ *out <<
+ "//Copyright (c) 2008-2017 Emil Dotchevski and Reverge Studios, Inc." NL
+ NL
+ "//Distributed under the Boost Software License, Version 1.0. (See accompanying" NL
+ "//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)" NL
+ NL
+ "#ifndef " << include_guard << NL
+ "#define " << include_guard << NL
+ NL
+ "//This file was generated by a program. Do not edit manually." NL
+ NL
+ ;
+ for( std::set<std::string>::const_iterator i=includes_.begin(),e=includes_.end(); i!=e; ++i )
+ *out << "#include <" << *i << ">" NL;
+ *out <<
+ NL
+ "namespace" NL
+ "boost" NL
+ TAB1 "{" NL
+ TAB1 "namespace" NL
+ TAB1 "qvm" NL
+ TAB2 "{" NL <<
+ out_.str() <<
+ TAB2 "}" NL
+ TAB1 "}" NL
+ NL
+ "#endif" NL
+ ;
+ }
+ };
+
+ void
+ replace( std::string & s, char const * substr, char const * newstr )
+ {
+ assert(substr && *substr);
+ assert(newstr && *newstr);
+ std::string::size_type f=s.find(substr);
+ if( s.npos!=f )
+ s.replace(f,f+strlen(substr),newstr);
+ }
+
+ std::string
+ deduce_name( std::string const & fn, char const * suffix )
+ {
+ std::string s=fn;
+ replace(s,"operator==","eq");
+ replace(s,"operator!=","neq");
+ replace(s,"operator+=","plus_eq");
+ replace(s,"operator-=","minus_eq");
+ replace(s,"operator*=","mul_eq");
+ replace(s,"operator/=","div_eq");
+ replace(s,"operator+","plus");
+ replace(s,"operator-","minus");
+ replace(s,"operator*","mul");
+ replace(s,"operator/","div");
+ if( suffix )
+ {
+ s += '_';
+ s += suffix;
+ }
+ return s;
+ }
+
+ void
+ header_mr_ma_mb_same_size( output_file & out, int r, int c, std::string const & name )
+ {
+ assert(r>0);
+ assert(c>0);
+ assert(!name.empty());
+ out.require_include(INCLUDE_DEDUCE_M);
+ out.stream() <<
+ TAB2 "template <class A,class B>" NL
+ TAB2 "BOOST_QVM_INLINE_OPERATIONS" NL
+ TAB2 "typename lazy_enable_if_c<" NL
+ TAB3 "mat_traits<A>::rows=="<<r<<" && mat_traits<B>::rows=="<<r<<" &&" NL
+ TAB3 "mat_traits<A>::cols=="<<c<<" && mat_traits<B>::cols=="<<c<<"," NL
+ TAB3 "deduce_mat2<A,B,"<<r<<','<<c<<"> >::type" NL
+ TAB2<<name<<"( A const & a, B const & b )" NL
+ ;
+ }
+
+ void
+ header_mr_ma_mb_mult( output_file & out, int m, int n, int p, std::string const & name )
+ {
+ assert(m>0);
+ assert(n>0);
+ assert(p>0);
+ assert(!name.empty());
+ out.require_include(INCLUDE_DEDUCE_M);
+ out.stream()<<
+ TAB2 "template <class A,class B>" NL
+ TAB2 "BOOST_QVM_INLINE_OPERATIONS" NL
+ TAB2 "typename lazy_enable_if_c<" NL
+ TAB3 "mat_traits<A>::rows=="<<m<<" && mat_traits<B>::rows=="<<n<<" &&" NL
+ TAB3 "mat_traits<A>::cols=="<<n<<" && mat_traits<B>::cols=="<<p<<"," NL
+ TAB3 "deduce_mat2<A,B,"<<m<<','<<p<<"> >::type" NL
+ TAB2<<name<<"( A const & a, B const & b )" NL
+ ;
+ }
+
+ void
+ header_vr_ma_vb_mult( output_file & out, int r, int c, std::string const & name )
+ {
+ assert(r>0);
+ assert(c>0);
+ assert(!name.empty());
+ out.require_include(INCLUDE_DEDUCE_V);
+ out.stream()<<
+ TAB2 "template <class A,class B>" NL
+ TAB2 "BOOST_QVM_INLINE_OPERATIONS" NL
+ TAB2 "typename lazy_enable_if_c<" NL
+ TAB3 "mat_traits<A>::rows=="<<r<<" && mat_traits<A>::cols=="<<c<<" &&" NL
+ TAB3 "vec_traits<B>::dim=="<<c<<"," NL
+ TAB3 "deduce_vec2<A,B,"<<c<<"> >::type" NL
+ TAB2<<name<<"( A const & a, B const & b )" NL
+ ;
+ }
+
+ void
+ header_vr_va_mb_mult( output_file & out, int r, int c, std::string const & name )
+ {
+ assert(r>0);
+ assert(c>0);
+ assert(!name.empty());
+ out.require_include(INCLUDE_DEDUCE_V);
+ out.stream()<<
+ TAB2 "template <class A,class B>" NL
+ TAB2 "BOOST_QVM_INLINE_OPERATIONS" NL
+ TAB2 "typename lazy_enable_if_c<" NL
+ TAB3 "mat_traits<B>::rows=="<<r<<" && mat_traits<B>::cols=="<<c<<" &&" NL
+ TAB3 "vec_traits<A>::dim=="<<c<<"," NL
+ TAB3 "deduce_vec2<A,B,"<<r<<"> >::type" NL
+ TAB2<<name<<"( A const & a, B const & b )" NL
+ ;
+ }
+
+ void
+ header_vr_va_vb_same_size( output_file & out, int d, std::string const & name )
+ {
+ assert(d>0);
+ assert(!name.empty());
+ out.require_include(INCLUDE_DEDUCE_V);
+ out.stream()<<
+ TAB2 "template <class A,class B>" NL
+ TAB2 "BOOST_QVM_INLINE_OPERATIONS" NL
+ TAB2 "typename lazy_enable_if_c<" NL
+ TAB3 "vec_traits<A>::dim=="<<d<<" && vec_traits<B>::dim=="<<d<<"," NL
+ TAB3 "deduce_vec2<A,B,"<<d<<"> >::type" NL
+ TAB2<<name<<"( A const & a, B const & b )" NL
+ ;
+ }
+
+ void
+ header_bool_ma_mb_same_size( output_file & out, int r, int c, std::string const & name )
+ {
+ assert(r>0);
+ assert(c>0);
+ assert(!name.empty());
+ out.stream()<<
+ TAB2 "template <class A,class B>" NL
+ TAB2 "BOOST_QVM_INLINE_OPERATIONS" NL
+ TAB2 "typename enable_if_c<" NL
+ TAB3 "mat_traits<A>::rows=="<<r<<" && mat_traits<B>::rows=="<<r<<" &&" NL
+ TAB3 "mat_traits<A>::cols=="<<c<<" && mat_traits<B>::cols=="<<c<<"," NL
+ TAB3 "bool>::type" NL
+ TAB2<<name<<"( A const & a, B const & b )" NL
+ ;
+ }
+
+ void
+ header_bool_va_vb_same_size( output_file & out, int d, std::string const & name )
+ {
+ assert(d>0);
+ assert(!name.empty());
+ out.stream()<<
+ TAB2 "template <class A,class B>" NL
+ TAB2 "BOOST_QVM_INLINE_OPERATIONS" NL
+ TAB2 "typename enable_if_c<" NL
+ TAB3 "vec_traits<A>::dim=="<<d<<" && vec_traits<B>::dim=="<<d<<"," NL
+ TAB2 "bool>::type" NL
+ TAB2<<name<<"( A const & a, B const & b )" NL
+ ;
+ }
+
+ void
+ header_ma_mb_same_size( output_file & out, int r, int c, std::string const & name )
+ {
+ assert(r>0);
+ assert(c>0);
+ assert(!name.empty());
+ out.stream()<<
+ TAB2 "template <class A,class B>" NL
+ TAB2 "BOOST_QVM_INLINE_OPERATIONS" NL
+ TAB2 "typename enable_if_c<" NL
+ TAB3 "mat_traits<A>::rows=="<<r<<" && mat_traits<B>::rows=="<<r<<" &&" NL
+ TAB3 "mat_traits<A>::cols=="<<c<<" && mat_traits<B>::cols=="<<c<<"," NL
+ TAB3 "A &>::type" NL
+ TAB2<<name<<"( A & a, B const & b )" NL
+ ;
+ }
+
+ void
+ header_va_vb_same_size( output_file & out, int d, std::string const & name )
+ {
+ assert(d>0);
+ assert(!name.empty());
+ out.stream()<<
+ TAB2 "template <class A,class B>" NL
+ TAB2 "BOOST_QVM_INLINE_OPERATIONS" NL
+ TAB2 "typename enable_if_c<" NL
+ TAB3 "vec_traits<A>::dim=="<<d<<" && vec_traits<B>::dim=="<<d<<"," NL
+ TAB3 "A &>::type" NL
+ TAB2<<name<<"( A & a, B const & b )" NL
+ ;
+ }
+
+ void
+ header_sr_ma( output_file & out, int r, int c, std::string const & name )
+ {
+ assert(r>0);
+ assert(c>0);
+ assert(!name.empty());
+ out.stream()<<
+ TAB2 "template <class A>" NL
+ TAB2 "BOOST_QVM_INLINE_OPERATIONS" NL
+ TAB2 "typename enable_if_c<" NL
+ TAB3 "mat_traits<A>::rows=="<<r<<" && mat_traits<A>::cols=="<<c<<"," NL
+ TAB3 "typename mat_traits<A>::scalar_type>::type" NL
+ TAB2<<name<<"( A const & a )" NL
+ ;
+ }
+
+ void
+ header_sr_va_vb( output_file & out, int d, std::string const & name )
+ {
+ assert(d>0);
+ assert(!name.empty());
+ out.require_include(INCLUDE_DEDUCE_S);
+ out.stream()<<
+ TAB2 "template <class A,class B>" NL
+ TAB2 "BOOST_QVM_INLINE_OPERATIONS" NL
+ TAB2 "typename lazy_enable_if_c<" NL
+ TAB3 "vec_traits<A>::dim=="<<d<<" && vec_traits<B>::dim=="<<d<<"," NL
+ TAB3 "deduce_scalar<typename vec_traits<A>::scalar_type,typename vec_traits<B>::scalar_type> >::type" NL
+ TAB2<<name<<"( A const & a, B const & b )" NL
+ ;
+ }
+
+ void
+ header_sr_va( output_file & out, int d, std::string const & name )
+ {
+ assert(d>0);
+ assert(!name.empty());
+ out.stream()<<
+ TAB2 "template <class A>" NL
+ TAB2 "BOOST_QVM_INLINE_OPERATIONS" NL
+ TAB2 "typename enable_if_c<" NL
+ TAB3 "is_vec<A>::value && vec_traits<A>::dim=="<<d<<"," NL
+ TAB3 "typename vec_traits<A>::scalar_type>::type" NL
+ TAB2<<name<<"( A const & a )" NL
+ ;
+ }
+
+ void
+ header_mr_ma( output_file & out, int r, int c, std::string const & name )
+ {
+ assert(r>0);
+ assert(c>0);
+ assert(!name.empty());
+ out.require_include(INCLUDE_DEDUCE_M);
+ out.stream()<<
+ TAB2 "template <class A>" NL
+ TAB2 "BOOST_QVM_INLINE_OPERATIONS" NL
+ TAB2 "typename lazy_enable_if_c<" NL
+ TAB3 "mat_traits<A>::rows=="<<r<<" && mat_traits<A>::cols=="<<c<<"," NL
+ TAB3 "deduce_mat<A> >::type" NL
+ TAB2<<name<<"( A const & a )" NL
+ ;
+ }
+
+ void
+ header_vr_va( output_file & out, int d, std::string const & name )
+ {
+ assert(d>0);
+ assert(!name.empty());
+ out.require_include(INCLUDE_DEDUCE_V);
+ out.stream()<<
+ TAB2 "template <class A>" NL
+ TAB2 "BOOST_QVM_INLINE_OPERATIONS" NL
+ TAB2 "typename lazy_enable_if_c<" NL
+ TAB3 "vec_traits<A>::dim=="<<d<<"," NL
+ TAB3 "deduce_vec<A> >::type" NL
+ TAB2<<name<<"( A const & a )" NL
+ ;
+ }
+
+ void
+ header_vr_va_same_size( output_file & out, int d, std::string const & name )
+ {
+ assert(d>0);
+ assert(!name.empty());
+ out.stream()<<
+ TAB2 "template <class R,class A>" NL
+ TAB2 "BOOST_QVM_INLINE_OPERATIONS" NL
+ TAB2 "typename enable_if_c<" NL
+ TAB3 "is_vec<A>::value &&" NL
+ TAB3 "vec_traits<R>::dim=="<<d<<" && vec_traits<A>::dim=="<<d<<"," NL
+ TAB3 "R>::type" NL
+ TAB2<<name<<"( A const & a )" NL
+ ;
+ }
+
+ void
+ header_mr_ma_sb( output_file & out, int r, int c, std::string const & name )
+ {
+ assert(r>0);
+ assert(c>0);
+ assert(!name.empty());
+ out.require_include(INCLUDE_DEDUCE_M);
+ out.stream()<<
+ TAB2 "template <class A,class B>" NL
+ TAB2 "BOOST_QVM_INLINE_OPERATIONS" NL
+ TAB2 "typename lazy_enable_if_c<" NL
+ TAB3 "mat_traits<A>::rows=="<<r<<" && mat_traits<A>::cols=="<<c<<" && is_scalar<B>::value," NL
+ TAB3 "deduce_mat<A> >::type" NL
+ TAB2<<name<<"( A const & a, B b )" NL
+ ;
+ }
+
+ void
+ header_mr_sa_mb( output_file & out, int r, int c, std::string const & name )
+ {
+ assert(r>0);
+ assert(c>0);
+ assert(!name.empty());
+ out.require_include(INCLUDE_DEDUCE_M);
+ out.stream()<<
+ TAB2 "template <class A,class B>" NL
+ TAB2 "BOOST_QVM_INLINE_OPERATIONS" NL
+ TAB2 "typename lazy_enable_if_c<" NL
+ TAB3 "is_scalar<A>::value && mat_traits<B>::rows=="<<r<<" && mat_traits<B>::cols=="<<c<<"," NL
+ TAB3 "deduce_mat<B> >::type" NL
+ TAB2<<name<<"( A a, B const & b )" NL
+ ;
+ }
+
+ void
+ header_vr_va_sb( output_file & out, int d, std::string const & name )
+ {
+ assert(d>0);
+ assert(!name.empty());
+ out.require_include(INCLUDE_DEDUCE_V);
+ out.stream()<<
+ TAB2 "template <class A,class B>" NL
+ TAB2 "BOOST_QVM_INLINE_OPERATIONS" NL
+ TAB2 "typename lazy_enable_if_c<" NL
+ TAB3 "vec_traits<A>::dim=="<<d<<" && is_scalar<B>::value," NL
+ TAB3 "deduce_vec<A> >::type" NL
+ TAB2<<name<<"( A const & a, B b )" NL
+ ;
+ }
+
+ void
+ header_vr_sa_vb( output_file & out, int d, std::string const & name )
+ {
+ assert(d>0);
+ assert(!name.empty());
+ out.require_include(INCLUDE_DEDUCE_V);
+ out.stream()<<
+ TAB2 "template <class A,class B>" NL
+ TAB2 "BOOST_QVM_INLINE_OPERATIONS" NL
+ TAB2 "typename lazy_enable_if_c<" NL
+ TAB3 "is_scalar<A>::value && vec_traits<B>::dim=="<<d<<"," NL
+ TAB3 "deduce_vec<B> >::type" NL
+ TAB2<<name<<"( A a, B const & b )" NL
+ ;
+ }
+
+ void
+ header_ma_sb( output_file & out, int r, int c, std::string const & name )
+ {
+ assert(r>0);
+ assert(c>0);
+ assert(!name.empty());
+ out.stream()<<
+ TAB2 "template <class A,class B>" NL
+ TAB2 "BOOST_QVM_INLINE_OPERATIONS" NL
+ TAB2 "typename enable_if_c<" NL
+ TAB3 "mat_traits<A>::rows=="<<r<<" && mat_traits<A>::cols=="<<c<<" && is_scalar<B>::value," NL
+ TAB3 "A &>::type" NL
+ TAB2<<name<<"( A & a, B b )" NL
+ ;
+ }
+
+ void
+ header_va_sb( output_file & out, int d, std::string const & name )
+ {
+ assert(d>0);
+ assert(!name.empty());
+ out.stream()<<
+ TAB2 "template <class A,class B>" NL
+ TAB2 "BOOST_QVM_INLINE_OPERATIONS" NL
+ TAB2 "typename enable_if_c<" NL
+ TAB3 "vec_traits<A>::dim=="<<d<<" && is_scalar<B>::value," NL
+ TAB3 "A &>::type" NL
+ TAB2<<name<<"( A & a, B b )" NL
+ ;
+ }
+
+ void
+ defined( std::ostream & g, int r, int cr, int c, std::string fn, char const * suffix )
+ {
+ assert(r>0);
+ assert(cr>0);
+ assert(c>0);
+ assert(!fn.empty());
+ std::string dn=deduce_name(fn,suffix);
+ std::string name=dn+"_defined";
+ g<<
+ NL
+ TAB2 "namespace" NL
+ TAB2 "sfinae" NL
+ TAB3 "{" NL
+ TAB3 "using ::boost::qvm::"<<fn<<";" NL
+ TAB3 "}" NL
+ NL
+ TAB2 "namespace" NL
+ TAB2 "qvm_detail" NL
+ TAB3 "{" NL
+ TAB3 "template <int R,int /*CR*/,int C>" NL
+ TAB3 "struct "<<name<<";" NL
+ NL
+ TAB3 "template <>" NL
+ TAB3 "struct" NL
+ TAB3<<name<<'<'<<r<<','<<cr<<','<<c<<">" NL
+ TAB4"{" NL
+ TAB4"static bool const value=true;" NL
+ TAB4"};" NL
+ TAB3 "}" NL
+ NL
+ ;
+ }
+
+ void
+ defined( std::ostream & g, int r, int c, std::string const & fn, char const * suffix )
+ {
+ assert(r>0);
+ assert(c>0);
+ assert(!fn.empty());
+ std::string dn=deduce_name(fn,suffix);
+ std::string name=dn+"_defined";
+ g<<
+ NL
+ TAB2 "namespace" NL
+ TAB2 "sfinae" NL
+ TAB3 "{" NL
+ TAB3 "using ::boost::qvm::"<<fn<<";" NL
+ TAB3 "}" NL
+ NL
+ TAB2 "namespace" NL
+ TAB2 "qvm_detail" NL
+ TAB3 "{" NL
+ TAB3 "template <int R,int C>" NL
+ TAB3 "struct "<<name<<";" NL
+ NL
+ TAB3 "template <>" NL
+ TAB3 "struct" NL
+ TAB3<<name<<"<"<<r<<","<<c<<">" NL
+ TAB4"{" NL
+ TAB4"static bool const value=true;" NL
+ TAB4"};" NL
+ TAB3 "}" NL
+ NL
+ ;
+ }
+
+ void
+ defined( std::ostream & g, int d, std::string const & fn, char const * suffix )
+ {
+ assert(d>0);
+ assert(!fn.empty());
+ std::string dn=deduce_name(fn,suffix);
+ std::string name=dn+"_defined";
+ g<<
+ NL
+ TAB2 "namespace" NL
+ TAB2 "sfinae" NL
+ TAB3 "{" NL
+ TAB3 "using ::boost::qvm::"<<fn<<";" NL
+ TAB3 "}" NL
+ NL
+ TAB2 "namespace" NL
+ TAB2 "qvm_detail" NL
+ TAB3 "{" NL
+ TAB3 "template <int D>" NL
+ TAB3 "struct "<<name<<";" NL
+ NL
+ TAB3 "template <>" NL
+ TAB3 "struct" NL
+ TAB3<<name<<"<"<<d<<">" NL
+ TAB4"{" NL
+ TAB4"static bool const value=true;" NL
+ TAB4"};" NL
+ TAB3 "}" NL
+ NL
+ ;
+ }
+
+ void
+ mr_mult_ma_mb( output_file & out, int m, int n, int p, char const * suffix )
+ {
+ assert(m>0);
+ assert(n>0);
+ assert(p>0);
+ header_mr_ma_mb_mult(out,m,n,p,"operator*");
+ out.require_include(INCLUDE_DEDUCE_M);
+ std::ostream & g=out.stream();
+ g<<
+ TAB3 "{" NL
+ TAB3 "typedef typename mat_traits<A>::scalar_type Ta;" NL
+ TAB3 "typedef typename mat_traits<B>::scalar_type Tb;" NL
+ ;
+ for( int i=0; i!=m; ++i )
+ for( int j=0; j!=n; ++j )
+ g<<TAB3 "Ta const a"<<i<<j<<" = mat_traits<A>::template read_element<"<<i<<','<<j<<">(a);" NL;
+ for( int i=0; i!=n; ++i )
+ for( int j=0; j!=p; ++j )
+ g<<TAB3 "Tb const b"<<i<<j<<" = mat_traits<B>::template read_element<"<<i<<','<<j<<">(b);" NL;
+ g<<
+ TAB3 "typedef typename deduce_mat2<A,B,"<<m<<','<<p<<">::type R;" NL
+ TAB3 "BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows=="<<m<<");" NL
+ TAB3 "BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols=="<<p<<");" NL
+ TAB3 "R r;" NL
+ ;
+ for( int i=0; i!=m; ++i )
+ for( int j=0; j!=p; ++j )
+ {
+ g<<TAB3 "mat_traits<R>::template write_element<"<<i<<","<<j<<">(r)=";
+ for( int k=0; k!=n; ++k )
+ {
+ if( k )
+ g<<'+';
+ g<<'a'<<i<<k<<"*b"<<k<<j;
+ }
+ g<<";" NL;
+ }
+ g<<
+ TAB3 "return r;" NL
+ TAB3 "}" NL
+ ;
+ defined(g,m,n,p,"operator*",suffix);
+ }
+
+ void
+ ma_mult_ma_mb( output_file & out, int d, char const * suffix )
+ {
+ assert(d>0);
+ header_ma_mb_same_size(out,d,d,"operator*=");
+ std::ostream & g=out.stream();
+ g<<
+ TAB3 "{" NL
+ TAB3 "typedef typename mat_traits<A>::scalar_type Ta;" NL
+ TAB3 "typedef typename mat_traits<B>::scalar_type Tb;" NL
+ ;
+ for( int i=0; i!=d; ++i )
+ for( int j=0; j!=d; ++j )
+ g<<TAB3 "Ta const a"<<i<<j<<" = mat_traits<A>::template read_element<"<<i<<','<<j<<">(a);" NL;
+ for( int i=0; i!=d; ++i )
+ for( int j=0; j!=d; ++j )
+ g<<TAB3 "Tb const b"<<i<<j<<" = mat_traits<B>::template read_element<"<<i<<','<<j<<">(b);" NL;
+ for( int i=0; i!=d; ++i )
+ for( int j=0; j!=d; ++j )
+ {
+ g<<TAB3 "mat_traits<A>::template write_element<"<<i<<","<<j<<">(a)=";
+ for( int k=0; k!=d; ++k )
+ {
+ if( k )
+ g<<'+';
+ g<<'a'<<i<<k<<"*b"<<k<<j;
+ }
+ g<<";" NL;
+ }
+ g<<
+ TAB3 "return a;" NL
+ TAB3 "}" NL
+ ;
+ defined(g,d,"operator*=",suffix);
+ }
+
+ void
+ vr_mult_ma_vb( output_file & out, int r, int c, char const * suffix )
+ {
+ assert(r>0);
+ assert(c>0);
+ header_vr_ma_vb_mult(out,r,c,"operator*");
+ out.require_include(INCLUDE_INLINE);
+ out.require_include(INCLUDE_V_TRAITS);
+ out.require_include(INCLUDE_M_TRAITS);
+ out.require_include(INCLUDE_ENABLE_IF);
+ out.require_include(INCLUDE_DEDUCE_V);
+ std::ostream & g=out.stream();
+ g<<
+ TAB3 "{" NL
+ TAB3 "typedef typename mat_traits<A>::scalar_type Ta;" NL
+ TAB3 "typedef typename vec_traits<B>::scalar_type Tb;" NL
+ ;
+ for( int i=0; i!=r; ++i )
+ for( int j=0; j!=c; ++j )
+ g<<TAB3 "Ta const a"<<i<<j<<" = mat_traits<A>::template read_element<"<<i<<','<<j<<">(a);" NL;
+ for( int i=0; i!=c; ++i )
+ g<<TAB3 "Tb const b"<<i<<" = vec_traits<B>::template read_element<"<<i<<">(b);" NL;
+ g<<
+ TAB3 "typedef typename deduce_vec2<A,B,"<<c<<">::type R;" NL
+ TAB3 "BOOST_QVM_STATIC_ASSERT(vec_traits<R>::dim=="<<c<<");" NL
+ TAB3 "R r;" NL
+ ;
+ for( int i=0; i!=r; ++i )
+ {
+ g<<TAB3 "vec_traits<R>::template write_element<"<<i<<">(r)=";
+ for( int j=0; j!=c; ++j )
+ {
+ if( j )
+ g<<'+';
+ g<<'a'<<i<<j<<"*b"<<j;
+ }
+ g<<";" NL;
+ }
+ g<<
+ TAB3 "return r;" NL
+ TAB3 "}" NL
+ ;
+ defined(g,r,c,"operator*",suffix);
+ }
+
+ void
+ vr_mult_va_mb( output_file & out, int r, int c, char const * suffix )
+ {
+ assert(r>0);
+ assert(c>0);
+ header_vr_va_mb_mult(out,r,c,"operator*");
+ out.require_include(INCLUDE_INLINE);
+ out.require_include(INCLUDE_V_TRAITS);
+ out.require_include(INCLUDE_M_TRAITS);
+ out.require_include(INCLUDE_ENABLE_IF);
+ out.require_include(INCLUDE_DEDUCE_V);
+ std::ostream & g=out.stream();
+ g<<
+ TAB3 "{" NL
+ TAB3 "typedef typename vec_traits<A>::scalar_type Ta;" NL
+ TAB3 "typedef typename mat_traits<B>::scalar_type Tb;" NL
+ ;
+ for( int i=0; i!=r; ++i )
+ g<<TAB3 "Ta const a"<<i<<" = vec_traits<A>::template read_element<"<<i<<">(a);" NL;
+ for( int i=0; i!=r; ++i )
+ for( int j=0; j!=c; ++j )
+ g<<TAB3 "Tb const b"<<i<<j<<" = mat_traits<B>::template read_element<"<<i<<','<<j<<">(b);" NL;
+ g<<
+ TAB3 "typedef typename deduce_vec2<A,B,"<<r<<">::type R;" NL
+ TAB3 "BOOST_QVM_STATIC_ASSERT(vec_traits<R>::dim=="<<r<<");" NL
+ TAB3 "R r;" NL
+ ;
+ for( int i=0; i!=c; ++i )
+ {
+ g<<TAB3 "vec_traits<R>::template write_element<"<<i<<">(r)=";
+ for( int j=0; j!=r; ++j )
+ {
+ if( j )
+ g<<'+';
+ g<<'a'<<j<<"*b"<<j<<i;
+ }
+ g<<";" NL;
+ }
+ g<<
+ TAB3 "return r;" NL
+ TAB3 "}" NL
+ ;
+ defined(g,r,c,"operator*",suffix);
+ }
+
+ void
+ vr_op_va_vb_same_size( output_file & out, int d, std::string const & fn, std::string const & op, char const * suffix )
+ {
+ assert(!op.empty());
+ header_vr_va_vb_same_size(out,d,fn);
+ out.require_include(INCLUDE_DEDUCE_V);
+ std::ostream & g=out.stream();
+ g<<
+ TAB3 "{" NL
+ TAB3 "typedef typename deduce_vec2<A,B,"<<d<<">::type R;" NL
+ TAB3 "BOOST_QVM_STATIC_ASSERT(vec_traits<R>::dim=="<<d<<");" NL
+ TAB3 "R r;" NL
+ ;
+ for( int i=0; i!=d; ++i )
+ g<<TAB3 "vec_traits<R>::template write_element<"<<i<<">(r)=vec_traits<A>::template read_element<"<<i<<">(a)"<<op<<"vec_traits<B>::template read_element<"<<i<<">(b);" NL;
+ g<<
+ TAB3 "return r;" NL
+ TAB3 "}" NL
+ ;
+ defined(g,d,fn,suffix);
+ }
+
+ void
+ bool_eq_ma_mb( output_file & out, int r, int c, char const * suffix )
+ {
+ header_bool_ma_mb_same_size(out,r,c,"operator==");
+ std::ostream & g=out.stream();
+ g<<
+ TAB3 "{" NL
+ TAB3 "return" NL
+ ;
+ for( int i=0; i!=r; ++i )
+ for( int j=0; j!=c; ++j )
+ g<<
+ TAB4"mat_traits<A>::template read_element<"<<i<<','<<j<<">(a)==mat_traits<B>::template read_element<"<<i<<','<<j<<">(b)"<<(i!=r-1||j!=c-1?" &&":";")<<NL;
+ ;
+ g<<
+ TAB3 "}" NL
+ ;
+ defined(g,r,c,"operator==",suffix);
+ }
+
+ void
+ bool_eq_va_vb( output_file & out, int d, char const * suffix )
+ {
+ header_bool_va_vb_same_size(out,d,"operator==");
+ std::ostream & g=out.stream();
+ g<<
+ TAB3 "{" NL
+ TAB3 "return" NL
+ ;
+ for( int i=0; i!=d; ++i )
+ g<<
+ TAB4"vec_traits<A>::template read_element<"<<i<<">(a)==vec_traits<B>::template read_element<"<<i<<">(b)"<<(i!=d-1?" &&":";")<<NL;
+ ;
+ g<<
+ TAB3 "}" NL
+ ;
+ defined(g,d,"operator==",suffix);
+ }
+
+ void
+ bool_neq_ma_mb( output_file & out, int r, int c, char const * suffix )
+ {
+ header_bool_ma_mb_same_size(out,r,c,"operator!=");
+ std::ostream & g=out.stream();
+ g<<
+ TAB3 "{" NL
+ TAB3 "return" NL
+ ;
+ for( int i=0; i!=r; ++i )
+ for( int j=0; j!=c; ++j )
+ g<<
+ TAB4"!(mat_traits<A>::template read_element<"<<i<<','<<j<<">(a)==mat_traits<B>::template read_element<"<<i<<','<<j<<">(b))"<<(i!=r-1||j!=c-1?" ||":";")<<NL;
+ ;
+ g<<
+ TAB3 "}" NL
+ ;
+ defined(g,r,c,"operator!=",suffix);
+ }
+
+ void
+ bool_neq_va_vb( output_file & out, int d, char const * suffix )
+ {
+ header_bool_va_vb_same_size(out,d,"operator!=");
+ std::ostream & g=out.stream();
+ g<<
+ TAB3 "{" NL
+ TAB3 "return" NL
+ ;
+ for( int i=0; i!=d; ++i )
+ g<<
+ TAB4"!(vec_traits<A>::template read_element<"<<i<<">(a)==vec_traits<B>::template read_element<"<<i<<">(b))"<<(i!=d-1?" ||":";")<<NL;
+ ;
+ g<<
+ TAB3 "}" NL
+ ;
+ defined(g,d,"operator!=",suffix);
+ }
+
+ void
+ mr_op_ma_mb_same_size( output_file & out, int r, int c, std::string const & fn, std::string const & op, char const * suffix )
+ {
+ assert(r>0);
+ assert(c>0);
+ assert(!op.empty());
+ header_mr_ma_mb_same_size(out,r,c,fn);
+ out.require_include(INCLUDE_DEDUCE_M);
+ std::ostream & g=out.stream();
+ g<<
+ TAB3 "{" NL
+ TAB3 "typedef typename deduce_mat2<A,B,"<<r<<','<<c<<">::type R;" NL
+ TAB3 "BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows=="<<r<<");" NL
+ TAB3 "BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols=="<<c<<");" NL
+ TAB3 "R r;" NL
+ ;
+ for( int i=0; i!=r; ++i )
+ for( int j=0; j!=c; ++j )
+ g<<TAB3 "mat_traits<R>::template write_element<"<<i<<","<<j<<">(r)=mat_traits<A>::template read_element<"<<i<<","<<j<<">(a)"<<op<<"mat_traits<B>::template read_element<"<<i<<","<<j<<">(b);" NL;
+ g<<
+ TAB3 "return r;" NL
+ TAB3 "}" NL
+ ;
+ defined(g,r,c,fn,suffix);
+ }
+
+ void
+ ma_op_ma_mb_same_size( output_file & out, int r, int c, std::string const & fn, std::string const & op, char const * suffix )
+ {
+ assert(!op.empty());
+ header_ma_mb_same_size(out,r,c,fn);
+ std::ostream & g=out.stream();
+ g<<TAB3 "{" NL;
+ for( int i=0; i!=r; ++i )
+ for( int j=0; j!=c; ++j )
+ g<<TAB3 "mat_traits<A>::template write_element<"<<i<<","<<j<<">(a)"<<op<<"mat_traits<B>::template read_element<"<<i<<","<<j<<">(b);" NL;
+ g<<
+ TAB3 "return a;" NL
+ TAB3 "}" NL
+ ;
+ defined(g,r,c,fn,suffix);
+ }
+
+ void
+ va_op_va_vb_same_size( output_file & out, int d, std::string const & fn, std::string const & op, char const * suffix )
+ {
+ assert(!op.empty());
+ header_va_vb_same_size(out,d,fn);
+ std::ostream & g=out.stream();
+ g<<TAB3 "{" NL;
+ for( int i=0; i!=d; ++i )
+ g<<TAB3 "vec_traits<A>::template write_element<"<<i<<">(a)"<<op<<"vec_traits<B>::template read_element<"<<i<<">(b);" NL;
+ g<<
+ TAB3 "return a;" NL
+ TAB3 "}" NL
+ ;
+ defined(g,d,fn,suffix);
+ }
+
+ void
+ mr_op_ma( output_file & out, int r, int c, std::string const & fn, std::string const & op, char const * suffix )
+ {
+ assert(!op.empty());
+ header_mr_ma(out,r,c,fn);
+ out.require_include(INCLUDE_DEDUCE_M);
+ std::ostream & g=out.stream();
+ g<<
+ TAB3 "{" NL
+ TAB3 "typedef typename deduce_mat<A>::type R;" NL
+ TAB3 "R r;" NL
+ ;
+ for( int i=0; i!=r; ++i )
+ for( int j=0; j!=c; ++j )
+ g<<TAB3 "mat_traits<R>::template write_element<"<<i<<","<<j<<">(r)="<<op<<"mat_traits<A>::template read_element<"<<i<<","<<j<<">(a);" NL;
+ g<<
+ TAB3 "return r;" NL
+ TAB3 "}" NL
+ ;
+ defined(g,r,c,fn,suffix);
+ }
+
+ void
+ vr_op_va( output_file & out, int d, std::string const & fn, std::string const & op, char const * suffix )
+ {
+ assert(!op.empty());
+ header_vr_va(out,d,fn);
+ out.require_include(INCLUDE_DEDUCE_V);
+ std::ostream & g=out.stream();
+ g<<
+ TAB3 "{" NL
+ TAB3 "typedef typename deduce_vec<A>::type R;" NL
+ TAB3 "R r;" NL
+ ;
+ for( int i=0; i!=d; ++i )
+ g<<TAB3 "vec_traits<R>::template write_element<"<<i<<">(r)="<<op<<"vec_traits<A>::template read_element<"<<i<<">(a);" NL;
+ g<<
+ TAB3 "return r;" NL
+ TAB3 "}" NL
+ ;
+ defined(g,d,fn,suffix);
+ }
+
+ void
+ mr_op_ma_sb( output_file & out, int r, int c, std::string const & fn, std::string const & op, char const * suffix )
+ {
+ assert(!op.empty());
+ header_mr_ma_sb(out,r,c,fn);
+ out.require_include(INCLUDE_DEDUCE_M);
+ out.require_include(INCLUDE_DEDUCE_V);
+ std::ostream & g=out.stream();
+ g<<
+ TAB3 "{" NL
+ TAB3 "typedef typename deduce_mat<A>::type R;" NL
+ TAB3 "R r;" NL
+ ;
+ for( int i=0; i!=r; ++i )
+ for( int j=0; j!=c; ++j )
+ g<<TAB3 "mat_traits<R>::template write_element<"<<i<<","<<j<<">(r)=mat_traits<A>::template read_element<"<<i<<","<<j<<">(a)"<<op<<"b;" NL;
+ g<<
+ TAB3 "return r;" NL
+ TAB3 "}" NL
+ ;
+ defined(g,r,c,fn,suffix);
+ }
+
+ void
+ mr_op_sa_mb( output_file & out, int r, int c, std::string const & fn, std::string const & op, char const * suffix )
+ {
+ assert(!op.empty());
+ header_mr_sa_mb(out,r,c,fn);
+ out.require_include(INCLUDE_DEDUCE_M);
+ out.require_include(INCLUDE_DEDUCE_V);
+ std::ostream & g=out.stream();
+ g<<
+ TAB3 "{" NL
+ TAB3 "typedef typename deduce_mat<B>::type R;" NL
+ TAB3 "R r;" NL
+ ;
+ for( int i=0; i!=r; ++i )
+ for( int j=0; j!=c; ++j )
+ g<<TAB3 "mat_traits<R>::template write_element<"<<i<<","<<j<<">(r)=a"<<op<<"mat_traits<B>::template read_element<"<<i<<","<<j<<">(b);" NL;
+ g<<
+ TAB3 "return r;" NL
+ TAB3 "}" NL
+ ;
+ defined(g,r,c,fn,suffix);
+ }
+
+ void
+ vr_op_va_sb( output_file & out, int d, std::string const & fn, std::string const & op, char const * suffix )
+ {
+ assert(!op.empty());
+ header_vr_va_sb(out,d,fn);
+ out.require_include(INCLUDE_DEDUCE_V);
+ std::ostream & g=out.stream();
+ g<<
+ TAB3 "{" NL
+ TAB3 "typedef typename deduce_vec<A>::type R;" NL
+ TAB3 "R r;" NL
+ ;
+ for( int i=0; i!=d; ++i )
+ g<<TAB3 "vec_traits<R>::template write_element<"<<i<<">(r)=vec_traits<A>::template read_element<"<<i<<">(a)"<<op<<"b;" NL;
+ g<<
+ TAB3 "return r;" NL
+ TAB3 "}" NL
+ ;
+ defined(g,d,fn,suffix);
+ }
+
+ void
+ vr_op_sa_vb( output_file & out, int d, std::string const & fn, std::string const & op, char const * suffix )
+ {
+ assert(!op.empty());
+ header_vr_sa_vb(out,d,fn);
+ out.require_include(INCLUDE_DEDUCE_V);
+ std::ostream & g=out.stream();
+ g<<
+ TAB3 "{" NL
+ TAB3 "typedef typename deduce_vec<B>::type R;" NL
+ TAB3 "R r;" NL
+ ;
+ for( int i=0; i!=d; ++i )
+ g<<TAB3 "vec_traits<R>::template write_element<"<<i<<">(r)=a"<<op<<"vec_traits<B>::template read_element<"<<i<<">(b);" NL;
+ g<<
+ TAB3 "return r;" NL
+ TAB3 "}" NL
+ ;
+ defined(g,d,fn,suffix);
+ }
+
+ void
+ ma_op_ma_sb( output_file & out, int r, int c, std::string const & fn, std::string const & op, char const * suffix )
+ {
+ assert(!op.empty());
+ header_ma_sb(out,r,c,fn);
+ std::ostream & g=out.stream();
+ g<<
+ TAB3 "{" NL
+ ;
+ for( int i=0; i!=r; ++i )
+ for( int j=0; j!=c; ++j )
+ g<<TAB3 "mat_traits<A>::template write_element<"<<i<<","<<j<<">(a)"<<op<<"b;" NL;
+ g<<
+ TAB3 "return a;" NL
+ TAB3 "}" NL
+ ;
+ defined(g,r,c,fn,suffix);
+ }
+
+ void
+ va_op_va_sb( output_file & out, int d, std::string const & fn, std::string const & op, char const * suffix )
+ {
+ assert(!op.empty());
+ header_va_sb(out,d,fn);
+ std::ostream & g=out.stream();
+ g<<
+ TAB3 "{" NL
+ ;
+ for( int i=0; i!=d; ++i )
+ g<<TAB3 "vec_traits<A>::template write_element<"<<i<<">(a)"<<op<<"b;" NL;
+ g<<
+ TAB3 "return a;" NL
+ TAB3 "}" NL
+ ;
+ defined(g,d,fn,suffix);
+ }
+
+ void
+ ma_assign_ma_mb( output_file & out, int r, int c, char const * suffix )
+ {
+ header_ma_mb_same_size(out,r,c,"assign");
+ out.require_include(INCLUDE_M_TRAITS);
+ out.require_include(INCLUDE_INLINE);
+ out.require_include(INCLUDE_ENABLE_IF);
+ std::ostream & g=out.stream();
+ g<<TAB3 "{" NL;
+ for( int i=0; i!=r; ++i )
+ for( int j=0; j!=c; ++j )
+ g<<TAB3 "mat_traits<A>::template write_element<"<<i<<","<<j<<">(a)=mat_traits<B>::template read_element<"<<i<<","<<j<<">(b);" NL;
+ g<<
+ TAB3 "return a;" NL
+ TAB3 "}" NL
+ ;
+ defined(g,r,c,"assign",suffix);
+ }
+
+ void
+ va_assign_va_vb( output_file & out, int d, char const * suffix )
+ {
+ header_va_vb_same_size(out,d,"assign");
+ out.require_include(INCLUDE_V_TRAITS);
+ out.require_include(INCLUDE_INLINE);
+ out.require_include(INCLUDE_ENABLE_IF);
+ std::ostream & g=out.stream();
+ g<<TAB3 "{" NL;
+ for( int i=0; i!=d; ++i )
+ g<<TAB3 "vec_traits<A>::template write_element<"<<i<<">(a)=vec_traits<B>::template read_element<"<<i<<">(b);" NL;
+ g<<
+ TAB3 "return a;" NL
+ TAB3 "}" NL
+ ;
+ defined(g,d,"assign",suffix);
+ }
+
+ void
+ mr_convert_to_ma( output_file & out, int r, int c, char const * suffix )
+ {
+ if( r==c && r>=3 )
+ {
+ out.require_include(INCLUDE_Q_TRAITS);
+ out.require_include(INCLUDE_S_TRAITS);
+ }
+ std::ostream & g=out.stream();
+ g<<
+ TAB2 "template <class R,class A>" NL
+ TAB2 "BOOST_QVM_INLINE_OPERATIONS" NL
+ TAB2 "typename enable_if_c<" NL
+ TAB3 "mat_traits<R>::rows=="<<r<<" && mat_traits<A>::rows=="<<r<<" &&" NL
+ TAB3 "mat_traits<R>::cols=="<<c<<" && mat_traits<A>::cols=="<<c<<"," NL
+ TAB3 "R>::type" NL
+ TAB2<<"convert_to( A const & a )" NL
+ TAB3 "{" NL
+ TAB3 "R r;" NL
+ ;
+ for( int i=0; i!=r; ++i )
+ for( int j=0; j!=c; ++j )
+ g<<TAB3 "mat_traits<R>::template write_element<"<<i<<","<<j<<">(r) = mat_traits<A>::template read_element<"<<i<<","<<j<<">(a);" NL;
+ g<<
+ TAB3 "return r;" NL
+ TAB3 "}" NL
+ ;
+ if( r==c && r>=3 )
+ {
+ g<<
+ NL
+ TAB2 "template <class R,class A>" NL
+ TAB2 "BOOST_QVM_INLINE" NL
+ TAB2 "typename enable_if_c<" NL
+ TAB3 "is_mat<R>::value && is_quat<A>::value &&" NL
+ TAB3 "mat_traits<R>::rows=="<<r<<" && mat_traits<R>::cols=="<<c<<"," NL
+ TAB3 "R>::type" NL
+ TAB2 "convert_to( A const & q )" NL
+ TAB3 "{" NL
+ TAB3 "typedef typename mat_traits<R>::scalar_type T;" NL
+ TAB3 "T const a=quat_traits<A>::template read_element<0>(q);" NL
+ TAB3 "T const b=quat_traits<A>::template read_element<1>(q);" NL
+ TAB3 "T const c=quat_traits<A>::template read_element<2>(q);" NL
+ TAB3 "T const d=quat_traits<A>::template read_element<3>(q);" NL
+ TAB3 "T const bb = b*b;" NL
+ TAB3 "T const cc = c*c;" NL
+ TAB3 "T const dd = d*d;" NL
+ TAB3 "T const bc = b*c;" NL
+ TAB3 "T const bd = b*d;" NL
+ TAB3 "T const cd = c*d;" NL
+ TAB3 "T const ab = a*b;" NL
+ TAB3 "T const ac = a*c;" NL
+ TAB3 "T const ad = a*d;" NL<<
+ (r>3?TAB3 "T const zero = scalar_traits<T>::value(0);" NL:"")<<
+ TAB3 "T const one = scalar_traits<T>::value(1);" NL
+ TAB3 "T const two = one+one;" NL
+ TAB3 "R r;" NL
+ TAB3 "mat_traits<R>::template write_element<0,0>(r) = one - two*(cc+dd);" NL
+ TAB3 "mat_traits<R>::template write_element<0,1>(r) = two*(bc-ad);" NL
+ TAB3 "mat_traits<R>::template write_element<0,2>(r) = two*(bd+ac);" NL
+ ;
+ for( int i=3; i!=c; ++i )
+ g<<TAB3 "mat_traits<R>::template write_element<0,"<<i<<">(r) = zero;" NL;
+ g<<
+ TAB3 "mat_traits<R>::template write_element<1,0>(r) = two*(bc+ad);" NL
+ TAB3 "mat_traits<R>::template write_element<1,1>(r) = one - two*(bb+dd);" NL
+ TAB3 "mat_traits<R>::template write_element<1,2>(r) = two*(cd-ab);" NL
+ ;
+ for( int i=3; i!=c; ++i )
+ g<<TAB3 "mat_traits<R>::template write_element<1,"<<i<<">(r) = zero;" NL;
+ g<<
+ TAB3 "mat_traits<R>::template write_element<2,0>(r) = two*(bd-ac);" NL
+ TAB3 "mat_traits<R>::template write_element<2,1>(r) = two*(cd+ab);" NL
+ TAB3 "mat_traits<R>::template write_element<2,2>(r) = one - two*(bb+cc);" NL
+ ;
+ for( int i=3; i!=c; ++i )
+ g<<TAB3 "mat_traits<R>::template write_element<2,"<<i<<">(r) = zero;" NL;
+ for( int i=3; i!=r; ++i )
+ for( int j=0; j!=c; ++j )
+ g<<TAB3 "mat_traits<R>::template write_element<"<<i<<","<<j<<">(r) = "<<(i==j?"one":"zero")<<";" NL;
+ g<<
+ TAB3 "return r;" NL
+ TAB3 "}" NL
+ ;
+ }
+ defined(g,r,c,"convert_to",suffix);
+ }
+
+ void
+ vr_convert_to_va( output_file & out, int d, char const * suffix )
+ {
+ header_vr_va_same_size(out,d,"convert_to");
+ std::ostream & g=out.stream();
+ g<<TAB3 "{" NL<<
+ TAB3 "R r;" NL
+ ;
+ for( int i=0; i!=d; ++i )
+ g<<TAB3 "vec_traits<R>::template write_element<"<<i<<">(r)=vec_traits<A>::template read_element<"<<i<<">(a);" NL;
+ g<<
+ TAB3 "return r;" NL
+ TAB3 "}" NL
+ ;
+ defined(g,d,"convert_to",suffix);
+ }
+
+ struct
+ del_row_col
+ {
+ del_row_col const * next;
+ int i, j;
+ char var;
+ explicit
+ del_row_col( char var ):
+ next(0),
+ i(std::numeric_limits<int>::max()),
+ j(std::numeric_limits<int>::max()),
+ var(var)
+ {
+ }
+ del_row_col( del_row_col const & next, int i, int j ):
+ next(&next),
+ i(i),
+ j(j),
+ var(next.var)
+ {
+ }
+ std::pair<int,int>
+ idx( std::pair<int,int> const & x ) const
+ {
+ std::pair<int,int> r(x.first+(x.first>=i),x.second+(x.second>=j));
+ if( next )
+ return next->idx(r);
+ else
+ return r;
+
+ }
+ void
+ operator()( std::ostream & g, int r, int c ) const
+ {
+ std::pair<int,int> p=idx(std::make_pair(r,c));
+ g << var << p.first << p.second;
+ }
+ };
+
+ void
+ determinant_impl( std::ostream & g, int n, del_row_col const & a )
+ {
+ if( n==1 )
+ return a(g,0,0);
+ g << "(";
+ char const * plus="";
+ for( int i=0; i!=n; ++i,plus="+" )
+ {
+ g<<((i&1)?"-":plus);
+ a(g,0,i);
+ g<<'*';
+ determinant_impl(g,n-1,del_row_col(a,0,i));
+ }
+ g << ")";
+ }
+
+ void
+ determinant( output_file & out, int d, char const * suffix )
+ {
+ header_sr_ma(out,d,d,"determinant");
+ std::ostream & g=out.stream();
+ g<<
+ TAB3 "{" NL
+ TAB3 "typedef typename mat_traits<A>::scalar_type T;" NL
+ ;
+ for( int i=0; i!=d; ++i )
+ for( int j=0; j!=d; ++j )
+ g<<TAB3<<"T const a"<<i<<j<<"=mat_traits<A>::template read_element<"<<i<<','<<j<<">(a);" NL;
+ g<<TAB3 "T det=";
+ determinant_impl(g,d,del_row_col('a'));
+ g<<";" NL;
+ g<<
+ TAB3 "return det;" NL
+ TAB3 "}" NL
+ ;
+ defined(g,d,"determinant",suffix);
+ }
+
+ void
+ inverse_ma( output_file & out, int d, char const * suffix )
+ {
+ assert(d>1);
+ out.require_include(INCLUDE_DEDUCE_M);
+ out.require_include(INCLUDE_ASSERT);
+ out.require_include(INCLUDE_THROW_EXCEPTION);
+ out.require_include(INCLUDE_ERROR);
+ std::ostream & g=out.stream();
+ g<<
+ TAB2 "template <class A,class B>" NL
+ TAB2 "BOOST_QVM_INLINE_OPERATIONS" NL
+ TAB2 "typename lazy_enable_if_c<" NL
+ TAB3 "mat_traits<A>::rows=="<<d<<" && mat_traits<A>::cols=="<<d<<" && is_scalar<B>::value," NL
+ TAB3 "deduce_mat<A> >::type" NL
+ TAB2 "inverse( A const & a, B det )" NL
+ TAB3 "{" NL
+ TAB3 "typedef typename mat_traits<A>::scalar_type T;" NL
+ TAB3 "BOOST_QVM_ASSERT(det!=scalar_traits<B>::value(0));" NL
+ ;
+ for( int i=0; i!=d; ++i )
+ for( int j=0; j!=d; ++j )
+ g<<TAB3 "T const a"<<i<<j<<"=mat_traits<A>::template read_element<"<<i<<','<<j<<">(a);" NL;
+ g<<
+ TAB3 "T const f=scalar_traits<T>::value(1)/det;" NL
+ TAB3 "typedef typename deduce_mat<A>::type R;" NL
+ TAB3 "R r;" NL
+ ;
+ for( int i=0; i!=d; ++i )
+ for( int j=0; j!=d; ++j )
+ {
+ g<<TAB3 "mat_traits<R>::template write_element<"<<i<<','<<j<<">(r)="<<(((i+j)&1)?'-':' ')<<"f*";
+ determinant_impl(g,d-1,del_row_col(del_row_col('a'),j,i));
+ g<<";" NL;
+ }
+ g<<
+ TAB3 "return r;" NL
+ TAB3 "}" NL
+ NL
+ TAB2 "template <class A>" NL
+ TAB2 "BOOST_QVM_INLINE_OPERATIONS" NL
+ TAB2 "typename lazy_enable_if_c<" NL
+ TAB3 "mat_traits<A>::rows=="<<d<<" && mat_traits<A>::cols=="<<d<<"," NL
+ TAB3 "deduce_mat<A> >::type" NL
+ TAB2 "inverse( A const & a )" NL
+ TAB3 "{" NL
+ TAB3 "typedef typename mat_traits<A>::scalar_type T;" NL
+ TAB3 "T det=determinant(a);" NL
+ TAB3 "if( det==scalar_traits<T>::value(0) )" NL
+ TAB4"BOOST_QVM_THROW_EXCEPTION(zero_determinant_error());" NL
+ TAB3 "return inverse(a,det);" NL
+ TAB3 "}" NL
+ ;
+ defined(g,d,"inverse",suffix);
+ }
+
+ void
+ mag_sqr( output_file & out, int d, char const * suffix )
+ {
+ header_sr_va(out,d,"mag_sqr");
+ out.require_include(INCLUDE_MATH);
+ std::ostream & g=out.stream();
+ g<<
+ TAB3 "{" NL
+ TAB3 "typedef typename vec_traits<A>::scalar_type T;" NL
+ ;
+ for( int i=0; i!=d; ++i )
+ g<<TAB3 "T const a"<<i<<"=vec_traits<A>::template read_element<"<<i<<">(a);" NL;
+ g<<TAB3 "T const m2=";
+ for( int i=0; i!=d; ++i )
+ {
+ if( i )
+ g<<'+';
+ g<<'a'<<i<<"*a"<<i;
+ }
+ g<<
+ ";" NL
+ TAB3 "return m2;" NL
+ TAB3 "}" NL
+ ;
+ defined(g,d,"mag_sqr",suffix);
+ }
+
+ void
+ mag( output_file & out, int d, char const * suffix )
+ {
+ header_sr_va(out,d,"mag");
+ out.require_include(INCLUDE_MATH);
+ std::ostream & g=out.stream();
+ g<<
+ TAB3 "{" NL
+ TAB3 "typedef typename vec_traits<A>::scalar_type T;" NL
+ ;
+ for( int i=0; i!=d; ++i )
+ g<<TAB3 "T const a"<<i<<"=vec_traits<A>::template read_element<"<<i<<">(a);" NL;
+ g<<TAB3 "T const m2=";
+ for( int i=0; i!=d; ++i )
+ {
+ if( i )
+ g<<'+';
+ g<<'a'<<i<<"*a"<<i;
+ }
+ g<<
+ ";" NL
+ TAB3 "T const mag=sqrt<T>(m2);" NL
+ TAB3 "return mag;" NL
+ TAB3 "}" NL
+ ;
+ defined(g,d,"mag",suffix);
+ }
+
+ void
+ normalize( output_file & out, int d, char const * suffix )
+ {
+ header_vr_va(out,d,"normalized");
+ out.require_include(INCLUDE_MATH);
+ out.require_include(INCLUDE_THROW_EXCEPTION);
+ out.require_include(INCLUDE_ERROR);
+ out.require_include(INCLUDE_DEDUCE_V);
+ std::ostream & g=out.stream();
+ g<<
+ TAB3 "{" NL
+ TAB3 "typedef typename vec_traits<A>::scalar_type T;" NL
+ ;
+ for( int i=0; i!=d; ++i )
+ g<<TAB3 "T const a"<<i<<"=vec_traits<A>::template read_element<"<<i<<">(a);" NL;
+ g<<TAB3 "T const m2=";
+ for( int i=0; i!=d; ++i )
+ {
+ if( i )
+ g<<'+';
+ g<<'a'<<i<<"*a"<<i;
+ }
+ g<<
+ ";" NL
+ TAB3 "if( m2==scalar_traits<typename vec_traits<A>::scalar_type>::value(0) )" NL
+ TAB4"BOOST_QVM_THROW_EXCEPTION(zero_magnitude_error());" NL
+ TAB3 "T const rm=scalar_traits<T>::value(1)/sqrt<T>(m2);" NL
+ TAB3 "typedef typename deduce_vec<A>::type R;" NL
+ TAB3 "R r;" NL
+ ;
+ for( int i=0; i!=d; ++i )
+ g<<TAB3 "vec_traits<R>::template write_element<"<<i<<">(r)=a"<<i<<"*rm;" NL;
+ g<<
+ TAB3 "return r;" NL
+ TAB3 "}" NL
+ NL
+ TAB2 "namespace" NL
+ TAB2 "sfinae" NL
+ TAB3 "{" NL
+ TAB3 "using ::boost::qvm::normalized;" NL
+ TAB3 "}" NL
+ NL
+ TAB2 "template <class A>" NL
+ TAB2 "BOOST_QVM_INLINE_OPERATIONS" NL
+ TAB2 "typename enable_if_c<" NL
+ TAB3 "vec_traits<A>::dim=="<<d<<"," NL
+ TAB3 "void>::type" NL
+ TAB2<<"normalize( A & a )" NL
+ TAB3 "{" NL
+ TAB3 "typedef typename vec_traits<A>::scalar_type T;" NL
+ ;
+ for( int i=0; i!=d; ++i )
+ g<<TAB3 "T const a"<<i<<"=vec_traits<A>::template read_element<"<<i<<">(a);" NL;
+ g<<TAB3 "T const m2=";
+ for( int i=0; i!=d; ++i )
+ {
+ if( i )
+ g<<'+';
+ g<<'a'<<i<<"*a"<<i;
+ }
+ g<<
+ ";" NL
+ TAB3 "if( m2==scalar_traits<typename vec_traits<A>::scalar_type>::value(0) )" NL
+ TAB4"BOOST_QVM_THROW_EXCEPTION(zero_magnitude_error());" NL
+ TAB3 "T const rm=scalar_traits<T>::value(1)/sqrt<T>(m2);" NL
+ ;
+ for( int i=0; i!=d; ++i )
+ g<<TAB3 "vec_traits<A>::template write_element<"<<i<<">(a)*=rm;" NL;
+ g<<TAB3 "}" NL;
+ defined(g,d,"normalize",suffix);
+ }
+
+ void
+ dot( output_file & out, int d, char const * suffix )
+ {
+ header_sr_va_vb(out,d,"dot");
+ out.require_include(INCLUDE_DEDUCE_S);
+ out.require_include(INCLUDE_STATIC_ASSERT);
+ std::ostream & g=out.stream();
+ g<<
+ TAB3 "{" NL
+ TAB3 "typedef typename vec_traits<A>::scalar_type Ta;" NL
+ TAB3 "typedef typename vec_traits<B>::scalar_type Tb;" NL
+ TAB3 "typedef typename deduce_scalar<Ta,Tb>::type Tr;" NL
+ ;
+ for( int i=0; i!=d; ++i )
+ g<<TAB3 "Ta const a"<<i<<"=vec_traits<A>::template read_element<"<<i<<">(a);" NL;
+ for( int i=0; i!=d; ++i )
+ g<<TAB3 "Tb const b"<<i<<"=vec_traits<B>::template read_element<"<<i<<">(b);" NL;
+ g<<TAB3 "Tr const dot=";
+ for( int i=0; i!=d; ++i )
+ {
+ if( i )
+ g<<'+';
+ g<<'a'<<i<<"*b"<<i;
+ }
+ g<<
+ ";" NL
+ TAB3 "return dot;" NL
+ TAB3 "}" NL
+ ;
+ defined(g,d,"dot",suffix);
+ }
+
+ struct
+ swizzle_pair
+ {
+ char ch;
+ int idx;
+ };
+
+ template <int N>
+ void
+ swizzle_impl( std::ostream & g, int d, swizzle_pair const (&ids)[N], std::vector<int> const & initial_count )
+ {
+ assert(d>=2);
+ std::vector<int> count(initial_count);
+ for( char const * const ref_id[2] = { " const &", " &" };; )
+ {
+ int max_dim=-100;
+ for( int i=0; i!=d; ++i )
+ max_dim=std::max(max_dim,ids[count[i]-1].idx);
+ if( max_dim<0 )
+ {
+ g<<
+ TAB2 "BOOST_QVM_INLINE_TRIVIAL" NL
+ TAB2 "qvm_detail::sw01_<";
+ for( int k=0; k!=d; ++k )
+ g<<(k?",":"")<<"qvm_detail::swizzle_idx<"<<ids[count[k]-1].idx;
+ for( int k=0; k!=d; ++k )
+ g<<" >";
+ g<<
+ " > const &" NL
+ TAB2 "_";
+ for( int k=0; k!=d; ++k )
+ {
+ char f=ids[count[k]-1].ch;
+ assert(f>='0' && f<='9');
+ g<<f;
+ }
+ g<<
+ "()" NL
+ TAB3 "{" NL
+ TAB3 "return *reinterpret_cast<qvm_detail::sw01_<";
+ for( int k=0; k!=d; ++k )
+ g<<(k?",":"")<<"qvm_detail::swizzle_idx<"<<ids[count[k]-1].idx;
+ for( int k=0; k!=d; ++k )
+ g<<" >";
+ g<<
+ " > const *>(qvm_detail::get_null());" NL
+ TAB3 "}" NL;
+ }
+ else
+ for( int rfid=0; rfid<2; ++rfid )
+ {
+ for( int scalar=0; scalar!=2; ++scalar )
+ {
+ if( scalar && max_dim>0 )
+ break;
+ if( scalar )
+ g<<
+ TAB2 "template <class S>" NL
+ TAB2 "BOOST_QVM_INLINE_TRIVIAL" NL
+ TAB2 "typename enable_if_c<" NL
+ TAB3 "is_scalar<S>::value," NL
+ TAB3 "qvm_detail::sws_<S,";
+ else
+ g<<
+ TAB2 "template <class V>" NL
+ TAB2 "BOOST_QVM_INLINE_TRIVIAL" NL
+ TAB2 "typename enable_if_c<" NL
+ TAB3 "is_vec<V>::value && vec_traits<V>::dim>="<<max_dim+1<<"," NL
+ TAB3 "qvm_detail::sw_<V,";
+ for( int k=0; k!=d; ++k )
+ g<<(k?",":"")<<"qvm_detail::swizzle_idx<"<<ids[count[k]-1].idx;
+ for( int k=0; k!=d; ++k )
+ g<<" >";
+ g<<" >"<<ref_id[rfid]<<">::type" NL TAB2;
+ for( int k=0; k!=d; ++k )
+ {
+ char f=ids[count[k]-1].ch;
+ if( !k && f>='0' && f<='9' )
+ g<<'_';
+ g<<f;
+ }
+ if( scalar )
+ g<<
+ "( S"<<ref_id[rfid]<<" a )" NL
+ TAB3 "{" NL
+ TAB3 "return reinterpret_cast<qvm_detail::sws_<S,";
+ else
+ g<<
+ "( V"<<ref_id[rfid]<<" a )" NL
+ TAB3 "{" NL
+ TAB3 "return reinterpret_cast<qvm_detail::sw_<V,";
+ for( int k=0; k!=d; ++k )
+ g<<(k?",":"")<<"qvm_detail::swizzle_idx<"<<ids[count[k]-1].idx;
+ for( int k=0; k!=d; ++k )
+ g<<" >";
+ g<<
+ " >"<<ref_id[rfid]<<">(a);" NL
+ TAB3 "}" NL;
+ }
+ }
+ int j;
+ for( j=0; j!=d; ++j )
+ if( --count[j] )
+ break;
+ else
+ count[j]=initial_count[j];
+ if( j==d )
+ break;
+ }
+ }
+
+ void
+ swizzle( output_file & out, int d )
+ {
+ assert(d>1);
+ out.require_include(INCLUDE_INLINE);
+ out.require_include(INCLUDE_SWIZZLE_TRAITS);
+ out.require_include(INCLUDE_ENABLE_IF);
+ std::ostream & g=out.stream();
+ swizzle_pair const swizzle_ids[6] =
+ {
+ {'X',0},
+ {'Y',1},
+ {'Z',2},
+ {'W',3},
+ {'0',-1},
+ {'1',-2}
+ };
+ std::vector<int> initial_count(d,6);
+ swizzle_impl(g,d,swizzle_ids,initial_count);
+ }
+
+ command_line_options
+ parse_command_line( int argc, char const * argv[] )
+ {
+ class
+ next
+ {
+ char const * const * const argv;
+ public:
+ int const argc;
+ next( int argc, char const * argv[] ):
+ argv(argv),
+ argc(argc)
+ {
+ }
+ std::string
+ operator()( int & i ) const
+ {
+ assert(i<argc);
+ if( ++i==argc )
+ BOOST_THROW_EXCEPTION(bad_command_line() << cmd_arg(argv[i-1]));
+ return argv[i];
+ }
+ } next_token(argc,argv);
+ command_line_options r;
+ for( int i=1; i!=argc; ++i )
+ if( argv[i][0]=='-' )
+ {
+ char const * arg=argv[i];
+ if( arg==std::string("-od") )
+ r.output_directory=next_token(i);
+ else if( arg==std::string("-con") )
+ r.con=true;
+ else
+ BOOST_THROW_EXCEPTION(bad_command_line() << cmd_arg(arg));
+ }
+ return r;
+ }
+
+ void
+ gen( int argc, char const * argv[] )
+ {
+ command_line_options opt=parse_command_line(argc,argv);
+ for( int d=2; d!=5; ++d )
+ {
+ output_file f(opt);
+ {
+ char buf[1024];
+ sprintf(buf,INCLUDE_MAT_ASSIGN,d);
+ f.require_include(buf);
+ }
+ mr_op_ma_mb_same_size(f,d,d,"operator+","+","mm");
+ mr_op_ma_mb_same_size(f,d,1,"operator+","+","mm");
+ mr_op_ma_mb_same_size(f,1,d,"operator+","+","mm");
+ mr_op_ma_mb_same_size(f,d,d,"operator-","-","mm");
+ mr_op_ma_mb_same_size(f,d,1,"operator-","-","mm");
+ mr_op_ma_mb_same_size(f,1,d,"operator-","-","mm");
+ ma_op_ma_mb_same_size(f,d,d,"operator+=","+=","mm");
+ ma_op_ma_mb_same_size(f,d,1,"operator+=","+=","mm");
+ ma_op_ma_mb_same_size(f,1,d,"operator+=","+=","mm");
+ ma_op_ma_mb_same_size(f,d,d,"operator-=","-=","mm");
+ ma_op_ma_mb_same_size(f,d,1,"operator-=","-=","mm");
+ ma_op_ma_mb_same_size(f,1,d,"operator-=","-=","mm");
+ mr_op_ma_sb(f,d,d,"operator*","*","ms");
+ mr_op_sa_mb(f,d,d,"operator*","*","sm");
+ mr_op_ma_sb(f,d,1,"operator*","*","ms");
+ mr_op_sa_mb(f,d,1,"operator*","*","sm");
+ mr_op_ma_sb(f,1,d,"operator*","*","ms");
+ mr_op_sa_mb(f,1,d,"operator*","*","sm");
+ ma_op_ma_sb(f,d,d,"operator*=","*=","ms");
+ ma_op_ma_sb(f,d,1,"operator*=","*=","ms");
+ ma_op_ma_sb(f,1,d,"operator*=","*=","ms");
+ mr_op_ma_sb(f,d,d,"operator/","/","ms");
+ mr_op_sa_mb(f,d,d,"operator/","/","sm");
+ mr_op_ma_sb(f,d,1,"operator/","/","ms");
+ mr_op_sa_mb(f,d,1,"operator/","/","sm");
+ mr_op_ma_sb(f,1,d,"operator/","/","ms");
+ ma_op_ma_sb(f,d,d,"operator/=","/=","ms");
+ ma_op_ma_sb(f,d,1,"operator/=","/=","ms");
+ ma_op_ma_sb(f,1,d,"operator/=","/=","ms");
+ mr_convert_to_ma(f,d,d,"m");
+ mr_convert_to_ma(f,d,1,"m");
+ mr_convert_to_ma(f,1,d,"m");
+ bool_eq_ma_mb(f,d,d,"mm");
+ bool_eq_ma_mb(f,d,1,"mm");
+ bool_eq_ma_mb(f,1,d,"mm");
+ bool_neq_ma_mb(f,d,d,"mm");
+ bool_neq_ma_mb(f,d,1,"mm");
+ bool_neq_ma_mb(f,1,d,"mm");
+ mr_op_ma(f,d,d,"operator-","-","m");
+ mr_op_ma(f,d,1,"operator-","-","m");
+ mr_op_ma(f,1,d,"operator-","-","m");
+ determinant(f,d,0);
+ inverse_ma(f,d,"m");
+ mr_mult_ma_mb(f,d,d,d,"mm");
+ ma_mult_ma_mb(f,d,"mm");
+ mr_mult_ma_mb(f,d,d,1,"mm");
+ mr_mult_ma_mb(f,1,d,d,"mm");
+ f.dump("mat_operations"+to_string(d)+".hpp");
+ }
+
+ for( int d=2; d!=5; ++d )
+ {
+ output_file f(opt);
+ ma_assign_ma_mb(f,d,d,"mm");
+ ma_assign_ma_mb(f,d,1,"mm");
+ ma_assign_ma_mb(f,1,d,"mm");
+ f.dump("mat_assign"+to_string(d)+".hpp");
+ }
+
+ for( int d=2; d!=5; ++d )
+ {
+ output_file f(opt);
+ {
+ char buf[1024];
+ sprintf(buf,INCLUDE_VEC_ASSIGN,d);
+ f.require_include(buf);
+ }
+ vr_op_va_vb_same_size(f,d,"operator+","+","vv");
+ vr_op_va_vb_same_size(f,d,"operator-","-","vv");
+ va_op_va_vb_same_size(f,d,"operator+=","+=","vv");
+ va_op_va_vb_same_size(f,d,"operator-=","-=","vv");
+ vr_op_va_sb(f,d,"operator*","*","vs");
+ vr_op_sa_vb(f,d,"operator*","*","sv");
+ va_op_va_sb(f,d,"operator*=","*=","vs");
+ vr_op_va_sb(f,d,"operator/","/","vs");
+ va_op_va_sb(f,d,"operator/=","/=","vs");
+ vr_convert_to_va(f,d,"v");
+ bool_eq_va_vb(f,d,"vv");
+ bool_neq_va_vb(f,d,"vv");
+ vr_op_va(f,d,"operator-","-","v");
+ mag(f,d,"v");
+ mag_sqr(f,d,"v");
+ normalize(f,d,"v");
+ dot(f,d,"vv");
+ f.dump("vec_operations"+to_string(d)+".hpp");
+ }
+
+ for( int d=2; d!=5; ++d )
+ {
+ output_file f(opt);
+ va_assign_va_vb(f,d,"vv");
+ f.dump("vec_assign"+to_string(d)+".hpp");
+ }
+
+ for( int d=2; d!=5; ++d )
+ {
+ output_file f(opt);
+ vr_mult_ma_vb(f,d,d,"mv");
+ vr_mult_va_mb(f,d,d,"vm");
+ f.dump("vec_mat_operations"+to_string(d)+".hpp");
+ }
+
+ {
+ output_file f(opt);
+ swizzle(f,2);
+ f.dump("swizzle2.hpp");
+ }
+ {
+ output_file f(opt);
+ swizzle(f,3);
+ f.dump("swizzle3.hpp");
+ }
+ {
+ output_file f(opt);
+ swizzle(f,4);
+ f.dump("swizzle4.hpp");
+ }
+ }
+ }
+
+int
+main( int argc, char const * argv[] )
+ {
+ try
+ {
+ gen(argc,argv);
+ }
+ catch(
+ std::ifstream::failure & )
+ {
+ std::cerr << "Failed to write generated output file" << std::endl;
+ }
+ catch(
+ ... )
+ {
+ std::cerr << "Unexpected exception" << std::endl << boost::current_exception_diagnostic_information();
+ }
+ return 1;
+ }
diff --git a/src/boost/libs/qvm/index.html b/src/boost/libs/qvm/index.html
new file mode 100644
index 000000000..d54c08f29
--- /dev/null
+++ b/src/boost/libs/qvm/index.html
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv=refresh content="0; URL=doc/html/index.html">
+<title>Automatic redirection</title>
+</head>
+<body>
+Automatic redirection failed, please go to
+<a href="doc/html/index.html">QVM</a>.&nbsp;<hr>
+</body>
+</html>
diff --git a/src/boost/libs/qvm/meta/libraries.json b/src/boost/libs/qvm/meta/libraries.json
new file mode 100644
index 000000000..51009d809
--- /dev/null
+++ b/src/boost/libs/qvm/meta/libraries.json
@@ -0,0 +1,17 @@
+{
+ "key": "qvm",
+ "name": "QVM",
+ "authors": [
+ "Emil Dotchevski"
+ ],
+ "description": "Generic {CPP} library for working with Quaternions Vectors and Matrices.",
+ "documentation": "index.html",
+ "category": [
+ "Generic",
+ "Math",
+ "Algorithms"
+ ],
+ "maintainers": [
+ "Emil Dotchevski <emil@revergestudios.com>"
+ ]
+}
diff --git a/src/boost/libs/qvm/test/Jamfile.v2 b/src/boost/libs/qvm/test/Jamfile.v2
new file mode 100644
index 000000000..6ab4858b9
--- /dev/null
+++ b/src/boost/libs/qvm/test/Jamfile.v2
@@ -0,0 +1,176 @@
+# Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+# Distributed under the Boost Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+import testing ;
+import path ;
+
+rule
+headers-compile-test ( headers * : requirements * : target-tag ? )
+ {
+ local test-names = ;
+ for local header in $(headers)
+ {
+ local target = hdr$(target-tag)-$(header:D=) ;
+ compile header-test.cpp : $(requirements) <define>REVERGE_HEADER=\"\<boost/qvm/$(header:B).hpp\>\" <dependency>$(header) : $(target) ;
+ test-names += $(target) ;
+ }
+ alias hdrtest$(target-tag) : $(test-names) ;
+ }
+
+headers-compile-test [ glob ../include/boost/qvm/*.hpp ]
+ : # requirements
+ : # target-tag
+ qvm
+ ;
+
+run math_test.cpp ;
+
+run mat_traits_array_test.cpp ;
+run vec_traits_array_test.cpp ;
+run quat_traits_array_test.cpp ;
+
+run access_m_test.cpp ;
+compile-fail access_m_fail1.cpp ;
+compile-fail access_m_fail2.cpp ;
+
+run access_q_test.cpp ;
+compile-fail access_q_fail.cpp ;
+
+run access_v_test.cpp ;
+compile-fail access_v_fail1.cpp ;
+compile-fail access_v_fail2.cpp ;
+
+run assign_test.cpp ;
+
+run to_string_test.cpp ;
+
+run cmp_vv_test.cpp ;
+run cross_test.cpp ;
+run div_eq_vs_test.cpp ;
+run div_vs_test.cpp ;
+run dot_vv_test.cpp ;
+run eq_vv_test.cpp ;
+run mag_v_test.cpp ;
+run mag_sqr_v_test.cpp ;
+run minus_v_test.cpp ;
+run minus_eq_vv_test.cpp ;
+run minus_vv_test.cpp ;
+run mul_eq_vs_test.cpp ;
+run mul_vs_test.cpp ;
+run mul_sv_test.cpp ;
+run mul_vm_test.cpp ;
+run normalize_v_test.cpp ;
+run plus_eq_vv_test.cpp ;
+run plus_vv_test.cpp ;
+run scalar_cast_v_test.cpp ;
+run vec_index_test.cpp ;
+run vec_register_test.cpp ;
+
+run cmp_mm_test.cpp ;
+run determinant_test.cpp ;
+run div_eq_ms_test.cpp ;
+run div_ms_test.cpp ;
+run eq_mm_test.cpp ;
+run minus_m_test.cpp ;
+run minus_eq_mm_test.cpp ;
+run minus_mm_test.cpp ;
+run mul_eq_mm_test.cpp ;
+run mul_eq_ms_test.cpp ;
+run mul_mm_test.cpp ;
+run mul_ms_test.cpp ;
+run mul_sm_test.cpp ;
+run mul_mv_test.cpp ;
+run inverse_m_test.cpp ;
+run plus_eq_mm_test.cpp ;
+run plus_mm_test.cpp ;
+run scalar_cast_m_test.cpp ;
+run mat_index_test.cpp ;
+
+run cmp_qq_test.cpp ;
+run conjugate_test.cpp ;
+run normalize_q_test.cpp ;
+run div_eq_qs_test.cpp ;
+run div_qs_test.cpp ;
+run dot_qq_test.cpp ;
+run eq_qq_test.cpp ;
+run inverse_q_test.cpp ;
+run mag_q_test.cpp ;
+run mag_sqr_q_test.cpp ;
+run minus_q_test.cpp ;
+run minus_eq_qq_test.cpp ;
+run minus_qq_test.cpp ;
+run mul_eq_qs_test.cpp ;
+run mul_qs_test.cpp ;
+run mul_qv_test.cpp ;
+run mul_qq_test.cpp ;
+run mul_eq_qq_test.cpp ;
+run plus_eq_qq_test.cpp ;
+run plus_qq_test.cpp ;
+run scalar_cast_q_test.cpp ;
+run slerp_test.cpp ;
+
+run convert_to_test.cpp ;
+
+run rot_mat_test.cpp ;
+run rot_quat_test.cpp ;
+run rotx_mat_test.cpp ;
+run rotx_quat_test.cpp ;
+run roty_mat_test.cpp ;
+run roty_quat_test.cpp ;
+run rotz_mat_test.cpp ;
+run rotz_quat_test.cpp ;
+
+run zero_vec_test.cpp ;
+run zero_mat_test.cpp ;
+run zero_quat_test.cpp ;
+run identity_mat_test.cpp ;
+run identity_quat_test.cpp ;
+
+run col_test.cpp ;
+run col_mat_test.cpp ;
+run neg_col_test.cpp ;
+run neg_row_test.cpp ;
+run del_col_test.cpp ;
+run del_row_test.cpp ;
+run del_row_col_test.cpp ;
+run swap_cols_test.cpp ;
+run swap_rows_test.cpp ;
+run diag_test.cpp ;
+run diag_mat_test.cpp ;
+run row_test.cpp ;
+run row_mat_test.cpp ;
+run transpose_test.cpp ;
+run translation_test.cpp ;
+run translation_mat_test.cpp ;
+
+compile-fail swizzle_const_fail.cpp ;
+run swizzle2_test2.cpp ;
+run swizzle2_test3.cpp ;
+run swizzle2_test4.cpp ;
+run swizzle2_test.cpp ;
+run swizzle3_test2.cpp ;
+run swizzle3_test3.cpp ;
+run swizzle3_test4.cpp ;
+run swizzle3_test.cpp ;
+run swizzle4_test2.cpp ;
+run swizzle4_test3.cpp ;
+run swizzle4_test4.cpp ;
+run swizzle4_test.cpp ;
+
+compile deduce_scalar_test.cpp ;
+compile-fail deduce_scalar_fail1.cpp ;
+compile-fail deduce_scalar_fail2.cpp ;
+compile-fail deduce_scalar_fail3.cpp ;
+
+compile deduce_matrix_test.cpp ;
+compile deduce_vector_test.cpp ;
+
+run interop_test.cpp ;
+
+run transform_test.cpp ;
+
+run projection_test.cpp ;
+
+compile scalar_traits_test.cpp ;
diff --git a/src/boost/libs/qvm/test/access_m_fail1.cpp b/src/boost/libs/qvm/test/access_m_fail1.cpp
new file mode 100644
index 000000000..f3d0d7152
--- /dev/null
+++ b/src/boost/libs/qvm/test/access_m_fail1.cpp
@@ -0,0 +1,36 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/mat_access.hpp>
+
+template <int R,int C> struct my_mat { };
+
+namespace
+boost
+ {
+ namespace
+ qvm
+ {
+ template <int R,int C>
+ struct
+ mat_traits< my_mat<R,C> >
+ {
+ typedef int scalar_type;
+ static int const rows=R;
+ static int const cols=C;
+ template <int Row,int Col> static int read_element( my_mat<R,C> const & );
+ template <int Row,int Col> static int & write_element( my_mat<R,C> & );
+ };
+ }
+ }
+
+int
+main()
+ {
+ using namespace boost::qvm;
+ my_mat<1,1> const m=my_mat<1,1>();
+ A11(m);
+ return 1;
+ }
diff --git a/src/boost/libs/qvm/test/access_m_fail2.cpp b/src/boost/libs/qvm/test/access_m_fail2.cpp
new file mode 100644
index 000000000..855b2d76d
--- /dev/null
+++ b/src/boost/libs/qvm/test/access_m_fail2.cpp
@@ -0,0 +1,36 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/mat_access.hpp>
+
+template <int R,int C> struct my_mat { };
+
+namespace
+boost
+ {
+ namespace
+ qvm
+ {
+ template <int R,int C>
+ struct
+ mat_traits< my_mat<R,C> >
+ {
+ typedef int scalar_type;
+ static int const rows=R;
+ static int const cols=C;
+ template <int Row,int Col> static int read_element( my_mat<R,C> const & );
+ template <int Row,int Col> static int & write_element( my_mat<R,C> & );
+ };
+ }
+ }
+
+int
+main()
+ {
+ using namespace boost::qvm;
+ my_mat<1,1> m;
+ A11(m);
+ return 1;
+ }
diff --git a/src/boost/libs/qvm/test/access_m_test.cpp b/src/boost/libs/qvm/test/access_m_test.cpp
new file mode 100644
index 000000000..3e8f0df64
--- /dev/null
+++ b/src/boost/libs/qvm/test/access_m_test.cpp
@@ -0,0 +1,126 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/mat_access.hpp>
+#include "test_qvm_matrix.hpp"
+
+using namespace boost::qvm;
+
+template <int R,int C>
+void
+check_idx( test_qvm::matrix<M1,10,10> & m, float & (*f)( test_qvm::matrix<M1,10,10> & ) )
+ {
+ BOOST_TEST((&A<R,C>(m)==&m.a[R][C]));
+ BOOST_TEST((&f(m)==&m.a[R][C]));
+ }
+
+int
+main()
+ {
+ test_qvm::matrix<M1,10,10> m;
+#define CHECK_A(i,j) check_idx<i,j>(m,A##i##j);
+ CHECK_A(0,0);
+ CHECK_A(0,1);
+ CHECK_A(0,2);
+ CHECK_A(0,3);
+ CHECK_A(0,4);
+ CHECK_A(0,5);
+ CHECK_A(0,6);
+ CHECK_A(0,7);
+ CHECK_A(0,8);
+ CHECK_A(0,9);
+ CHECK_A(1,0);
+ CHECK_A(1,1);
+ CHECK_A(1,2);
+ CHECK_A(1,3);
+ CHECK_A(1,4);
+ CHECK_A(1,5);
+ CHECK_A(1,6);
+ CHECK_A(1,7);
+ CHECK_A(1,8);
+ CHECK_A(1,9);
+ CHECK_A(2,0);
+ CHECK_A(2,1);
+ CHECK_A(2,2);
+ CHECK_A(2,3);
+ CHECK_A(2,4);
+ CHECK_A(2,5);
+ CHECK_A(2,6);
+ CHECK_A(2,7);
+ CHECK_A(2,8);
+ CHECK_A(2,9);
+ CHECK_A(3,0);
+ CHECK_A(3,1);
+ CHECK_A(3,2);
+ CHECK_A(3,3);
+ CHECK_A(3,4);
+ CHECK_A(3,5);
+ CHECK_A(3,6);
+ CHECK_A(3,7);
+ CHECK_A(3,8);
+ CHECK_A(3,9);
+ CHECK_A(4,0);
+ CHECK_A(4,1);
+ CHECK_A(4,2);
+ CHECK_A(4,3);
+ CHECK_A(4,4);
+ CHECK_A(4,5);
+ CHECK_A(4,6);
+ CHECK_A(4,7);
+ CHECK_A(4,8);
+ CHECK_A(4,9);
+ CHECK_A(5,0);
+ CHECK_A(5,1);
+ CHECK_A(5,2);
+ CHECK_A(5,3);
+ CHECK_A(5,4);
+ CHECK_A(5,5);
+ CHECK_A(5,6);
+ CHECK_A(5,7);
+ CHECK_A(5,8);
+ CHECK_A(5,9);
+ CHECK_A(6,0);
+ CHECK_A(6,1);
+ CHECK_A(6,2);
+ CHECK_A(6,3);
+ CHECK_A(6,4);
+ CHECK_A(6,5);
+ CHECK_A(6,6);
+ CHECK_A(6,7);
+ CHECK_A(6,8);
+ CHECK_A(6,9);
+ CHECK_A(7,0);
+ CHECK_A(7,1);
+ CHECK_A(7,2);
+ CHECK_A(7,3);
+ CHECK_A(7,4);
+ CHECK_A(7,5);
+ CHECK_A(7,6);
+ CHECK_A(7,7);
+ CHECK_A(7,8);
+ CHECK_A(7,9);
+ CHECK_A(8,0);
+ CHECK_A(8,1);
+ CHECK_A(8,2);
+ CHECK_A(8,3);
+ CHECK_A(8,4);
+ CHECK_A(8,5);
+ CHECK_A(8,6);
+ CHECK_A(8,7);
+ CHECK_A(8,8);
+ CHECK_A(8,9);
+ CHECK_A(9,0);
+ CHECK_A(9,1);
+ CHECK_A(9,2);
+ CHECK_A(9,3);
+ CHECK_A(9,4);
+ CHECK_A(9,5);
+ CHECK_A(9,6);
+ CHECK_A(9,7);
+ CHECK_A(9,8);
+ CHECK_A(9,9);
+#undef CHECK_A
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/access_q_fail.cpp b/src/boost/libs/qvm/test/access_q_fail.cpp
new file mode 100644
index 000000000..fdeb7efc6
--- /dev/null
+++ b/src/boost/libs/qvm/test/access_q_fail.cpp
@@ -0,0 +1,35 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/quat_access.hpp>
+#include <boost/qvm/vec_access.hpp>
+
+struct my_quat { };
+
+namespace
+boost
+ {
+ namespace
+ qvm
+ {
+ template <>
+ struct
+ quat_traits<my_quat>
+ {
+ typedef int scalar_type;
+ template <int I> static int read_element( my_quat const & );
+ template <int I> static int & write_element( my_quat & );
+ };
+ }
+ }
+
+int
+main()
+ {
+ using namespace boost::qvm;
+ my_quat const q=my_quat();
+ A<3>(V(q));
+ return 1;
+ }
diff --git a/src/boost/libs/qvm/test/access_q_test.cpp b/src/boost/libs/qvm/test/access_q_test.cpp
new file mode 100644
index 000000000..063c2e50d
--- /dev/null
+++ b/src/boost/libs/qvm/test/access_q_test.cpp
@@ -0,0 +1,39 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/quat_access.hpp>
+#include <boost/qvm/vec_access.hpp>
+#include "test_qvm_quaternion.hpp"
+
+int
+main()
+ {
+ using namespace boost::qvm;
+
+ test_qvm::quaternion<Q1> q;
+ q.a[0]=42.0f;
+ q.a[1]=43.0f;
+ q.a[2]=44.0f;
+ q.a[3]=45.0f;
+ test_qvm::quaternion<Q1> const & qq=q;
+
+ BOOST_TEST_EQ(X(V(qq)),q.a[1]);
+ BOOST_TEST_EQ(Y(V(qq)),q.a[2]);
+ BOOST_TEST_EQ(Z(V(qq)),q.a[3]);
+ BOOST_TEST(&X(V(q))==&q.a[1]);
+ BOOST_TEST(&Y(V(q))==&q.a[2]);
+ BOOST_TEST(&Z(V(q))==&q.a[3]);
+
+ BOOST_TEST_EQ(S(qq),q.a[0]);
+ BOOST_TEST_EQ(X(qq),q.a[1]);
+ BOOST_TEST_EQ(Y(qq),q.a[2]);
+ BOOST_TEST_EQ(Z(qq),q.a[3]);
+ BOOST_TEST(&S(q)==&q.a[0]);
+ BOOST_TEST(&X(q)==&q.a[1]);
+ BOOST_TEST(&Y(q)==&q.a[2]);
+ BOOST_TEST(&Z(q)==&q.a[3]);
+
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/access_v_fail1.cpp b/src/boost/libs/qvm/test/access_v_fail1.cpp
new file mode 100644
index 000000000..cd801767b
--- /dev/null
+++ b/src/boost/libs/qvm/test/access_v_fail1.cpp
@@ -0,0 +1,35 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_access.hpp>
+
+template <int D> struct my_vec { };
+
+namespace
+boost
+ {
+ namespace
+ qvm
+ {
+ template <int D>
+ struct
+ vec_traits< my_vec<D> >
+ {
+ typedef int scalar_type;
+ static int const dim=D;
+ template <int I> static int read_element( my_vec<D> const & );
+ template <int I> static int & write_element( my_vec<D> & );
+ };
+ }
+ }
+
+int
+main()
+ {
+ using namespace boost::qvm;
+ my_vec<1> const v=my_vec<1>();
+ A1(v);
+ return 1;
+ }
diff --git a/src/boost/libs/qvm/test/access_v_fail2.cpp b/src/boost/libs/qvm/test/access_v_fail2.cpp
new file mode 100644
index 000000000..c2feb4da7
--- /dev/null
+++ b/src/boost/libs/qvm/test/access_v_fail2.cpp
@@ -0,0 +1,35 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_access.hpp>
+
+template <int D> struct my_vec { };
+
+namespace
+boost
+ {
+ namespace
+ qvm
+ {
+ template <int D>
+ struct
+ vec_traits< my_vec<D> >
+ {
+ typedef int scalar_type;
+ static int const dim=D;
+ template <int I> static int read_element( my_vec<D> const & );
+ template <int I> static int & write_element( my_vec<D> & );
+ };
+ }
+ }
+
+int
+main()
+ {
+ using namespace boost::qvm;
+ my_vec<1> v;
+ A1(v);
+ return 1;
+ }
diff --git a/src/boost/libs/qvm/test/access_v_test.cpp b/src/boost/libs/qvm/test/access_v_test.cpp
new file mode 100644
index 000000000..9d355a372
--- /dev/null
+++ b/src/boost/libs/qvm/test/access_v_test.cpp
@@ -0,0 +1,40 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_access.hpp>
+#include "test_qvm_vector.hpp"
+
+using namespace boost::qvm;
+
+template <int I>
+void
+check_idx( test_qvm::vector<V1,10> & v, float & (*f)( test_qvm::vector<V1,10> & ) )
+ {
+ BOOST_TEST((&A<I>(v)==&v.a[I]));
+ BOOST_TEST((&f(v)==&v.a[I]));
+ }
+
+int
+main()
+ {
+ test_qvm::vector<V1,10> v;
+#define CHECK_A(i) check_idx<i>(v,A##i);
+ CHECK_A(0);
+ CHECK_A(1);
+ CHECK_A(2);
+ CHECK_A(3);
+ CHECK_A(4);
+ CHECK_A(5);
+ CHECK_A(6);
+ CHECK_A(7);
+ CHECK_A(8);
+ CHECK_A(9);
+#undef CHECK_A
+ BOOST_TEST(&A<0>(v)==&X(v));
+ BOOST_TEST(&A<1>(v)==&Y(v));
+ BOOST_TEST(&A<2>(v)==&Z(v));
+ BOOST_TEST(&A<3>(v)==&W(v));
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/assign_test.cpp b/src/boost/libs/qvm/test/assign_test.cpp
new file mode 100644
index 000000000..96ff1cea3
--- /dev/null
+++ b/src/boost/libs/qvm/test/assign_test.cpp
@@ -0,0 +1,70 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/quat_operations.hpp>
+#include <boost/qvm/vec_operations.hpp>
+#include <boost/qvm/mat_operations.hpp>
+#include "test_qvm_matrix.hpp"
+#include "test_qvm_quaternion.hpp"
+#include "test_qvm_vector.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Rows,int Cols>
+ void
+ test_matrix()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::matrix<M1,Rows,Cols> const x(42,1);
+ test_qvm::matrix<M2,Rows,Cols> y(43,1);
+ assign(y,x);
+ BOOST_QVM_TEST_EQ(x.a,y.a);
+ }
+
+ template <int Dim>
+ void
+ test_vector()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::vector<V1,Dim> const x(42,1);
+ test_qvm::vector<V2,Dim> y(43,1);
+ assign(y,x);
+ BOOST_QVM_TEST_EQ(x.a,y.a);
+ }
+
+ void
+ test_quaternion()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::quaternion<Q1> const x(42,1);
+ test_qvm::quaternion<Q2> y(43,1);
+ assign(y,x);
+ BOOST_QVM_TEST_EQ(x.a,y.a);
+ }
+ }
+
+int
+main()
+ {
+ test_matrix<1,2>();
+ test_matrix<2,1>();
+ test_matrix<2,2>();
+ test_matrix<1,3>();
+ test_matrix<3,1>();
+ test_matrix<3,3>();
+ test_matrix<1,4>();
+ test_matrix<4,1>();
+ test_matrix<4,4>();
+ test_matrix<1,5>();
+ test_matrix<5,1>();
+ test_matrix<5,5>();
+ test_vector<2>();
+ test_vector<3>();
+ test_vector<4>();
+ test_vector<5>();
+ test_quaternion();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/cmp_mm_test.cpp b/src/boost/libs/qvm/test/cmp_mm_test.cpp
new file mode 100644
index 000000000..8b4bee5c1
--- /dev/null
+++ b/src/boost/libs/qvm/test/cmp_mm_test.cpp
@@ -0,0 +1,107 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/mat_traits_array.hpp>
+#include <boost/qvm/mat.hpp>
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Rows,int Cols>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::matrix<M1,Rows,Cols> const x(42,1);
+ for( int i=0; i!=Rows; ++i )
+ for( int j=0; j!=Cols; ++j )
+ {
+ {
+ test_qvm::matrix<M1,Rows,Cols> y(x);
+ BOOST_QVM_TEST_EQ(x,y);
+ y.a[i][j]=0;
+ BOOST_QVM_TEST_NEQ(x,y);
+ }
+ {
+ test_qvm::matrix<M2,Rows,Cols> y; assign(y,x);
+ BOOST_QVM_TEST_EQ(x,y);
+ y.a[i][j]=0;
+ BOOST_QVM_TEST_NEQ(x,y);
+ }
+ }
+ }
+
+ template <class T>
+ struct test_scalar
+ {
+ T value_;
+ test_scalar( T value ): value_(value) {}
+ }; //No operator==
+
+ struct
+ equal_to
+ {
+ template <class T,class U>
+ bool
+ operator()( T const & a, U const & b )
+ {
+ return a.value_==b.value_;
+ }
+ };
+
+ template <class A, class B>
+ void
+ test2()
+ {
+ typedef test_scalar<A> scalar_a;
+ typedef test_scalar<B> scalar_b;
+ typedef boost::qvm::mat<scalar_a, 3, 3> mat_a;
+ typedef boost::qvm::mat<scalar_b, 3, 3> mat_b;
+ mat_a const a = { { {42, 94, 96}, {72, 95, 81}, {12, 84, 33} } };
+ mat_b const b = { { {42, 94, 96}, {72, 95, 81}, {12, 84, 33} } };
+ mat_a const c = { { {21, 47, 48}, {36, 47, 65}, {79, 27, 41} } };
+ mat_b const d = { { {21, 47, 48}, {36, 47, 65}, {79, 27, 41} } };
+ BOOST_TEST(cmp(a,a,equal_to()));
+ BOOST_TEST(cmp(a,b,equal_to()));
+ BOOST_TEST(cmp(b,a,equal_to()));
+ BOOST_TEST(cmp(b,b,equal_to()));
+ BOOST_TEST(cmp(c,c,equal_to()));
+ BOOST_TEST(cmp(c,d,equal_to()));
+ BOOST_TEST(cmp(d,c,equal_to()));
+ BOOST_TEST(cmp(d,d,equal_to()));
+ BOOST_TEST(!cmp(a,c,equal_to()));
+ BOOST_TEST(!cmp(c,a,equal_to()));
+ BOOST_TEST(!cmp(a,d,equal_to()));
+ BOOST_TEST(!cmp(d,a,equal_to()));
+ BOOST_TEST(!cmp(b,c,equal_to()));
+ BOOST_TEST(!cmp(c,b,equal_to()));
+ BOOST_TEST(!cmp(b,d,equal_to()));
+ BOOST_TEST(!cmp(d,b,equal_to()));
+ }
+ }
+
+int
+main()
+ {
+ test<1,2>();
+ test<2,1>();
+ test<2,2>();
+ test<1,3>();
+ test<3,1>();
+ test<3,3>();
+ test<1,4>();
+ test<4,1>();
+ test<4,4>();
+ test<1,5>();
+ test<5,1>();
+ test<5,5>();
+ test2<int, int>();
+ test2<int, double>();
+ test2<double, int>();
+ test2<double, double>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/cmp_qq_test.cpp b/src/boost/libs/qvm/test/cmp_qq_test.cpp
new file mode 100644
index 000000000..6d71f8573
--- /dev/null
+++ b/src/boost/libs/qvm/test/cmp_qq_test.cpp
@@ -0,0 +1,35 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Qersion 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/quat_operations.hpp>
+#include "test_qvm_quaternion.hpp"
+#include "gold.hpp"
+#include <functional>
+
+namespace
+ {
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::quaternion<Q1> const x(42,1);
+ for( int i=0; i!=4; ++i )
+ {
+ {
+ test_qvm::quaternion<Q1> y(x);
+ BOOST_TEST(cmp(x,y,std::equal_to<float>()));
+ y.a[i]=0;
+ BOOST_TEST(!cmp(x,y,std::equal_to<float>()));
+ }
+ }
+ }
+ }
+
+int
+main()
+ {
+ test();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/cmp_vv_test.cpp b/src/boost/libs/qvm/test/cmp_vv_test.cpp
new file mode 100644
index 000000000..87e23cc7b
--- /dev/null
+++ b/src/boost/libs/qvm/test/cmp_vv_test.cpp
@@ -0,0 +1,94 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+//Copyright (c) 2019 agate-pris
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec.hpp>
+#include <boost/qvm/vec_operations.hpp>
+#include <boost/qvm/vec_traits_array.hpp>
+#include "test_qvm_vector.hpp"
+#include "gold.hpp"
+#include <functional>
+
+namespace
+ {
+ template <int Dim>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::vector<V1,Dim> const x(42,1);
+ for( int i=0; i!=Dim; ++i )
+ {
+ {
+ test_qvm::vector<V1,Dim> y(x);
+ BOOST_TEST(cmp(x,y,std::equal_to<float>()));
+ y.a[i]=0;
+ BOOST_TEST(!cmp(x,y,std::equal_to<float>()));
+ }
+ }
+ }
+
+ template <class T>
+ struct test_scalar
+ {
+ T value_;
+ test_scalar( T value ): value_(value) {}
+ }; //No operator==
+
+ struct
+ equal_to
+ {
+ template <class T,class U>
+ bool
+ operator()( T const & a, U const & b )
+ {
+ return a.value_==b.value_;
+ }
+ };
+
+ template <class A, class B>
+ void
+ test2()
+ {
+ typedef test_scalar<A> scalar_a;
+ typedef test_scalar<B> scalar_b;
+ typedef boost::qvm::vec<scalar_a, 5> vec_a;
+ typedef boost::qvm::vec<scalar_b, 5> vec_b;
+ vec_a const a = { { 42, 94, 96, 72, 95 } };
+ vec_b const b = { { 42, 94, 96, 72, 95 } };
+ vec_a const c = { { 21, 47, 48, 36, 47 } };
+ vec_b const d = { { 21, 47, 48, 36, 47 } };
+ BOOST_TEST(cmp(a,a,equal_to()));
+ BOOST_TEST(cmp(a,b,equal_to()));
+ BOOST_TEST(cmp(b,a,equal_to()));
+ BOOST_TEST(cmp(b,b,equal_to()));
+ BOOST_TEST(cmp(c,c,equal_to()));
+ BOOST_TEST(cmp(c,d,equal_to()));
+ BOOST_TEST(cmp(d,c,equal_to()));
+ BOOST_TEST(cmp(d,d,equal_to()));
+ BOOST_TEST(!cmp(a,c,equal_to()));
+ BOOST_TEST(!cmp(c,a,equal_to()));
+ BOOST_TEST(!cmp(a,d,equal_to()));
+ BOOST_TEST(!cmp(d,a,equal_to()));
+ BOOST_TEST(!cmp(b,c,equal_to()));
+ BOOST_TEST(!cmp(c,b,equal_to()));
+ BOOST_TEST(!cmp(b,d,equal_to()));
+ BOOST_TEST(!cmp(d,b,equal_to()));
+ }
+ }
+
+int
+main()
+ {
+ test<2>();
+ test<3>();
+ test<4>();
+ test<5>();
+ test2<int, int>();
+ test2<int, double>();
+ test2<double, int>();
+ test2<double, double>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/col_mat_test.cpp b/src/boost/libs/qvm/test/col_mat_test.cpp
new file mode 100644
index 000000000..6d325971e
--- /dev/null
+++ b/src/boost/libs/qvm/test/col_mat_test.cpp
@@ -0,0 +1,40 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/map.hpp>
+#include <boost/qvm/mat_traits_array.hpp>
+#include <boost/qvm/vec_operations.hpp>
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/mat.hpp>
+#include "test_qvm_vector.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Dim>
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ test_qvm::vector<V1,Dim> x(42,1);
+ float y[1][Dim]; assign(y,transposed(col_mat(x)));
+ BOOST_QVM_TEST_EQ(x.a,y[0]);
+ test_qvm::scalar_multiply_v(x.b,x.a,2.0f);
+ col<0>(col_mat(x)) *= 2;
+ BOOST_QVM_TEST_EQ(x.a,x.b);
+ col_mat(x)+col_mat(x);
+ -col_mat(x);
+ }
+ }
+
+int
+main()
+ {
+ test<2>();
+ test<3>();
+ test<4>();
+ test<5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/col_test.cpp b/src/boost/libs/qvm/test/col_test.cpp
new file mode 100644
index 000000000..238c97e90
--- /dev/null
+++ b/src/boost/libs/qvm/test/col_test.cpp
@@ -0,0 +1,118 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/map_mat_vec.hpp>
+#include <boost/qvm/vec_traits_array.hpp>
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/vec_operations.hpp>
+#include <boost/qvm/vec.hpp>
+#include "test_qvm.hpp"
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Rows,int Cols,int Col>
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ test_qvm::matrix<M1,Rows,Cols> x(42,1);
+ float r1[Rows];
+ for( int i=0; i!=Rows; ++i )
+ r1[i]=x.a[i][Col];
+ float r2[Rows];
+ assign(r2,col<Col>(x));
+ BOOST_QVM_TEST_EQ(r1,r2);
+ col<Col>(x) *= 2;
+ for( int i=0; i!=Rows; ++i )
+ r1[i]=x.a[i][Col];
+ assign(r2,col<Col>(x));
+ BOOST_QVM_TEST_EQ(r1,r2);
+ col<Col>(x) + col<Col>(x);
+ -col<Col>(x);
+ }
+ }
+
+int
+main()
+ {
+ test<1,2,0>();
+ test<1,2,1>();
+ test<1,3,0>();
+ test<1,3,1>();
+ test<1,3,2>();
+ test<1,4,0>();
+ test<1,4,1>();
+ test<1,4,2>();
+ test<1,4,3>();
+ test<1,5,0>();
+ test<1,5,1>();
+ test<1,5,2>();
+ test<1,5,3>();
+ test<1,5,4>();
+
+ test<2,2,0>();
+ test<2,2,1>();
+ test<2,3,0>();
+ test<2,3,1>();
+ test<2,3,2>();
+ test<2,4,0>();
+ test<2,4,1>();
+ test<2,4,2>();
+ test<2,4,3>();
+ test<2,5,0>();
+ test<2,5,1>();
+ test<2,5,2>();
+ test<2,5,3>();
+ test<2,5,4>();
+
+ test<3,2,0>();
+ test<3,2,1>();
+ test<3,3,0>();
+ test<3,3,1>();
+ test<3,3,2>();
+ test<3,4,0>();
+ test<3,4,1>();
+ test<3,4,2>();
+ test<3,4,3>();
+ test<3,5,0>();
+ test<3,5,1>();
+ test<3,5,2>();
+ test<3,5,3>();
+ test<3,5,4>();
+
+ test<4,2,0>();
+ test<4,2,1>();
+ test<4,3,0>();
+ test<4,3,1>();
+ test<4,3,2>();
+ test<4,4,0>();
+ test<4,4,1>();
+ test<4,4,2>();
+ test<4,4,3>();
+ test<4,5,0>();
+ test<4,5,1>();
+ test<4,5,2>();
+ test<4,5,3>();
+ test<4,5,4>();
+
+ test<5,2,0>();
+ test<5,2,1>();
+ test<5,3,0>();
+ test<5,3,1>();
+ test<5,3,2>();
+ test<5,4,0>();
+ test<5,4,1>();
+ test<5,4,2>();
+ test<5,4,3>();
+ test<5,5,0>();
+ test<5,5,1>();
+ test<5,5,2>();
+ test<5,5,3>();
+ test<5,5,4>();
+
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/conjugate_test.cpp b/src/boost/libs/qvm/test/conjugate_test.cpp
new file mode 100644
index 000000000..ca1ac69e4
--- /dev/null
+++ b/src/boost/libs/qvm/test/conjugate_test.cpp
@@ -0,0 +1,41 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/quat_operations.hpp>
+#include <boost/qvm/quat.hpp>
+#include "test_qvm_quaternion.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <class T,class U> struct same_type_tester;
+ template <class T> struct same_type_tester<T,T> { };
+ template <class T,class U> void test_same_type( T, U ) { same_type_tester<T,U>(); }
+
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::quaternion<Q1> const x(42,1);
+ test_qvm::scalar_multiply_v(x.b,x.a,-1.0f);
+ x.b[0]=-x.b[0];
+ test_same_type(x,conjugate(x));
+ {
+ test_qvm::quaternion<Q1> y=conjugate(x);
+ BOOST_QVM_TEST_EQ(x.b,y.a);
+ }
+ {
+ test_qvm::quaternion<Q1> y=conjugate(qref(x));
+ BOOST_QVM_TEST_EQ(x.b,y.a);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/convert_to_test.cpp b/src/boost/libs/qvm/test/convert_to_test.cpp
new file mode 100644
index 000000000..c1d0edfea
--- /dev/null
+++ b/src/boost/libs/qvm/test/convert_to_test.cpp
@@ -0,0 +1,86 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/operations.hpp>
+#include <boost/qvm/map_mat_mat.hpp>
+#include "test_qvm_matrix.hpp"
+#include "test_qvm_quaternion.hpp"
+#include "test_qvm_vector.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Rows,int Cols>
+ void
+ test_matrix()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::matrix<M1,Rows,Cols> const x(42,1);
+ test_qvm::matrix<M2,Rows,Cols> const y=convert_to< test_qvm::matrix<M2,Rows,Cols> >(x);
+ BOOST_QVM_TEST_EQ(x.a,y.a);
+ }
+
+ template <int Dim>
+ void
+ test_vector()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::vector<V1,Dim> const x(42,1);
+ test_qvm::vector<V2,Dim> const y=convert_to< test_qvm::vector<V2,Dim> >(x);
+ BOOST_QVM_TEST_EQ(x.a,y.a);
+ }
+
+ void
+ test_quaternion()
+ {
+ using namespace boost::qvm;
+ test_qvm::quaternion<Q1> x(42,1);
+ normalize(x);
+ {
+ test_qvm::quaternion<Q2> const y=convert_to< test_qvm::quaternion<Q2> >(x);
+ BOOST_QVM_TEST_EQ(x.a,y.a);
+ }
+ {
+ test_qvm::matrix<M1,3,3> const my=convert_to< test_qvm::matrix<M1,3,3> >(x);
+ test_qvm::quaternion<Q1> const qy=convert_to< test_qvm::quaternion<Q1> >(my);
+ BOOST_QVM_TEST_CLOSE(x.a,qy.a,0.00001f);
+ }
+ {
+ test_qvm::matrix<M1,4,4> const my=convert_to< test_qvm::matrix<M1,4,4> >(x);
+ BOOST_TEST(my.a[0][3]==0);
+ BOOST_TEST(my.a[1][3]==0);
+ BOOST_TEST(my.a[2][3]==0);
+ BOOST_TEST(my.a[3][0]==0);
+ BOOST_TEST(my.a[3][1]==0);
+ BOOST_TEST(my.a[3][2]==0);
+ BOOST_TEST(my.a[3][3]==1);
+ test_qvm::quaternion<Q1> const qy=convert_to< test_qvm::quaternion<Q1> >(del_row_col<3,3>(my));
+ BOOST_QVM_TEST_CLOSE(x.a,qy.a,0.00001f);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test_matrix<1,2>();
+ test_matrix<2,1>();
+ test_matrix<2,2>();
+ test_matrix<1,3>();
+ test_matrix<3,1>();
+ test_matrix<3,3>();
+ test_matrix<1,4>();
+ test_matrix<4,1>();
+ test_matrix<4,4>();
+ test_matrix<1,5>();
+ test_matrix<5,1>();
+ test_matrix<5,5>();
+ test_quaternion();
+ test_vector<2>();
+ test_vector<3>();
+ test_vector<4>();
+ test_vector<5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/cross_test.cpp b/src/boost/libs/qvm/test/cross_test.cpp
new file mode 100644
index 000000000..9f752a171
--- /dev/null
+++ b/src/boost/libs/qvm/test/cross_test.cpp
@@ -0,0 +1,56 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_operations.hpp>
+#include <boost/qvm/vec_access.hpp>
+#include <boost/qvm/mat_access.hpp>
+#include <boost/qvm/vec_operations3.hpp>
+#include <boost/qvm/vec.hpp>
+//#include <boost/qvm/quat_traits.hpp>
+#include "test_qvm_vector.hpp"
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <class T,class U> struct same_type_tester;
+ template <class T> struct same_type_tester<T,T> { };
+ template <class T,class U> void test_same_type( T, U ) { same_type_tester<T,U>(); }
+ }
+
+int
+main()
+ {
+ using namespace boost::qvm;
+ test_qvm::vector<V1,3> x(42,1);
+ test_qvm::vector<V1,3> y=x*2;
+ test_qvm::matrix<M1,3,3> m;
+ A00(m) = 0;
+ A01(m) = -A2(x);
+ A02(m) = A1(x);
+ A10(m) = A2(x);
+ A11(m) = 0;
+ A12(m) = -A0(x);
+ A20(m) = -A1(x);
+ A21(m) = A0(x);
+ A22(m) = 0;
+ {
+ test_same_type(x,cross(x,y));
+ test_qvm::vector<V1,3> c=cross(x,y);
+ test_qvm::multiply_mv(c.b,m.a,y.a);
+ BOOST_QVM_TEST_EQ(c.a,c.b);
+ }
+ {
+ test_qvm::vector<V2,3> c=cross(vref(x),y);
+ test_qvm::multiply_mv(c.b,m.a,y.a);
+ BOOST_QVM_TEST_EQ(c.a,c.b);
+ }
+ {
+ test_qvm::vector<V2,3> c=cross(x,vref(y));
+ test_qvm::multiply_mv(c.b,m.a,y.a);
+ BOOST_QVM_TEST_EQ(c.a,c.b);
+ }
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/deduce_matrix_test.cpp b/src/boost/libs/qvm/test/deduce_matrix_test.cpp
new file mode 100644
index 000000000..769b790da
--- /dev/null
+++ b/src/boost/libs/qvm/test/deduce_matrix_test.cpp
@@ -0,0 +1,51 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/deduce_mat.hpp>
+
+template <class T,class U>
+struct same_type;
+
+template <class T>
+struct
+same_type<T,T>
+ {
+ };
+
+template <class A,class B,int R,int C,class Result>
+struct
+check
+ {
+ same_type<typename boost::qvm::deduce_mat2<A,B,R,C>::type,Result> a;
+ same_type<typename boost::qvm::deduce_mat2<B,A,R,C>::type,Result> b;
+ };
+
+template <class T,int R,int C> struct m;
+
+namespace
+boost
+ {
+ namespace
+ qvm
+ {
+ template <class T,int R,int C>
+ struct
+ mat_traits< m<T,R,C> >
+ {
+ typedef T scalar_type;
+ static int const rows=R;
+ static int const cols=C;
+ };
+ }
+ }
+
+int
+main()
+ {
+ same_type< boost::qvm::deduce_mat< m<int,4,2> >::type, m<int,4,2> >();
+ same_type< boost::qvm::deduce_mat< m<int,4,2>, 4, 4 >::type, boost::qvm::mat<int,4,4> >();
+ check< m<int,4,2>, m<int,4,2>, 4, 2, m<int,4,2> >();
+ check< m<int,4,2>, m<float,4,2>, 4, 4, boost::qvm::mat<float,4,4> >();
+ }
diff --git a/src/boost/libs/qvm/test/deduce_scalar_fail1.cpp b/src/boost/libs/qvm/test/deduce_scalar_fail1.cpp
new file mode 100644
index 000000000..00442c85f
--- /dev/null
+++ b/src/boost/libs/qvm/test/deduce_scalar_fail1.cpp
@@ -0,0 +1,8 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/deduce_scalar.hpp>
+
+typedef boost::qvm::deduce_scalar<char,int>::type char_scalars_not_supported_use_signed_char_instead;
diff --git a/src/boost/libs/qvm/test/deduce_scalar_fail2.cpp b/src/boost/libs/qvm/test/deduce_scalar_fail2.cpp
new file mode 100644
index 000000000..c9b8df260
--- /dev/null
+++ b/src/boost/libs/qvm/test/deduce_scalar_fail2.cpp
@@ -0,0 +1,9 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/deduce_scalar.hpp>
+
+struct foo;
+typedef boost::qvm::deduce_scalar<foo,int>::type user_defined_types_require_specialization;
diff --git a/src/boost/libs/qvm/test/deduce_scalar_fail3.cpp b/src/boost/libs/qvm/test/deduce_scalar_fail3.cpp
new file mode 100644
index 000000000..101a1e0c1
--- /dev/null
+++ b/src/boost/libs/qvm/test/deduce_scalar_fail3.cpp
@@ -0,0 +1,10 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/deduce_scalar.hpp>
+
+struct foo;
+struct bar;
+typedef boost::qvm::deduce_scalar<foo,bar>::type user_defined_types_require_specialization;
diff --git a/src/boost/libs/qvm/test/deduce_scalar_test.cpp b/src/boost/libs/qvm/test/deduce_scalar_test.cpp
new file mode 100644
index 000000000..cfb12c284
--- /dev/null
+++ b/src/boost/libs/qvm/test/deduce_scalar_test.cpp
@@ -0,0 +1,77 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/deduce_scalar.hpp>
+
+template <class T,class U>
+struct same_type;
+
+template <class T>
+struct
+same_type<T,T>
+ {
+ };
+
+template <class A,class B,class R>
+struct
+check
+ {
+ same_type<typename boost::qvm::deduce_scalar<A,B>::type,R> a;
+ same_type<typename boost::qvm::deduce_scalar<B,A>::type,R> b;
+ };
+
+int
+main()
+ {
+ check<signed char,signed char,signed char>();
+ check<signed char,signed short,signed short>();
+ check<signed char,signed int,signed int>();
+ check<signed char,signed long,signed long>();
+ check<signed char,unsigned char,unsigned char>();
+ check<signed char,unsigned short,unsigned short>();
+ check<signed char,unsigned int,unsigned int>();
+ check<signed char,unsigned long,unsigned long>();
+ check<signed char,float,float>();
+ check<signed char,double,double>();
+ check<signed short,signed short,signed short>();
+ check<signed short,signed int,signed int>();
+ check<signed short,signed long,signed long>();
+ check<signed short,unsigned short,unsigned short>();
+ check<signed short,unsigned int,unsigned int>();
+ check<signed short,unsigned long,unsigned long>();
+ check<signed short,float,float>();
+ check<signed short,double,double>();
+ check<signed int,signed int,signed int>();
+ check<signed int,signed long,signed long>();
+ check<signed int,unsigned int,unsigned int>();
+ check<signed int,unsigned long,unsigned long>();
+ check<signed int,float,float>();
+ check<signed int,double,double>();
+ check<signed long,signed long,signed long>();
+ check<signed long,unsigned long,unsigned long>();
+ check<signed long,float,float>();
+ check<signed long,double,double>();
+ check<unsigned char,unsigned char,unsigned char>();
+ check<unsigned char,unsigned short,unsigned short>();
+ check<unsigned char,unsigned int,unsigned int>();
+ check<unsigned char,unsigned long,unsigned long>();
+ check<unsigned char,float,float>();
+ check<unsigned char,double,double>();
+ check<unsigned short,unsigned short,unsigned short>();
+ check<unsigned short,unsigned int,unsigned int>();
+ check<unsigned short,unsigned long,unsigned long>();
+ check<unsigned short,float,float>();
+ check<unsigned short,double,double>();
+ check<unsigned int,unsigned int,unsigned int>();
+ check<unsigned int,unsigned long,unsigned long>();
+ check<unsigned int,float,float>();
+ check<unsigned int,double,double>();
+ check<unsigned long,unsigned long,unsigned long>();
+ check<unsigned long,float,float>();
+ check<unsigned long,double,double>();
+ check<float,float,float>();
+ check<float,double,double>();
+ check<double,double,double>();
+ }
diff --git a/src/boost/libs/qvm/test/deduce_vector_test.cpp b/src/boost/libs/qvm/test/deduce_vector_test.cpp
new file mode 100644
index 000000000..f2b0ab031
--- /dev/null
+++ b/src/boost/libs/qvm/test/deduce_vector_test.cpp
@@ -0,0 +1,50 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/deduce_vec.hpp>
+
+template <class T,class U>
+struct same_type;
+
+template <class T>
+struct
+same_type<T,T>
+ {
+ };
+
+template <class A,class B,int D,class Result>
+struct
+check
+ {
+ same_type<typename boost::qvm::deduce_vec2<A,B,D>::type,Result> a;
+ same_type<typename boost::qvm::deduce_vec2<B,A,D>::type,Result> b;
+ };
+
+template <class T,int D> struct v;
+
+namespace
+boost
+ {
+ namespace
+ qvm
+ {
+ template <class T,int D>
+ struct
+ vec_traits< v<T,D> >
+ {
+ typedef T scalar_type;
+ static int const dim=D;
+ };
+ }
+ }
+
+int
+main()
+ {
+ same_type< boost::qvm::deduce_vec< v<int,3> >::type, v<int,3> >();
+ same_type< boost::qvm::deduce_vec< v<int,3>, 4 >::type, boost::qvm::vec<int,4> >();
+ check< v<int,3>, v<int,3>, 3, v<int,3> >();
+ check< v<int,3>, v<float,3>, 4, boost::qvm::vec<float,4> >();
+ }
diff --git a/src/boost/libs/qvm/test/del_col_test.cpp b/src/boost/libs/qvm/test/del_col_test.cpp
new file mode 100644
index 000000000..09ffccbf7
--- /dev/null
+++ b/src/boost/libs/qvm/test/del_col_test.cpp
@@ -0,0 +1,61 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/map_mat_mat.hpp>
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/mat_traits_array.hpp>
+#include <boost/qvm/mat.hpp>
+#include "test_qvm.hpp"
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Rows,int Cols,int Col>
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ test_qvm::matrix<M1,Rows,Cols> x(42,1);
+ float r1[Rows][Cols-1];
+ for( int i=0; i!=Rows; ++i )
+ for( int j=0; j!=Cols-1; ++j )
+ r1[i][j]=x.a[i][j+(j>=Col)];
+ float r2[Rows][Cols-1];
+ assign(r2,del_col<Col>(x));
+ BOOST_QVM_TEST_EQ(r1,r2);
+ del_col<Col>(x) *= 2;
+ for( int i=0; i!=Rows; ++i )
+ for( int j=0; j!=Cols-1; ++j )
+ r1[i][j]=x.a[i][j+(j>=Col)];
+ assign(r2,del_col<Col>(x));
+ BOOST_QVM_TEST_EQ(r1,r2);
+ del_col<Col>(x) + del_col<Col>(x);
+ -del_col<Col>(x);
+ }
+ }
+
+int
+main()
+ {
+ test<2,2,0>();
+ test<2,2,1>();
+
+ test<3,3,0>();
+ test<3,3,1>();
+ test<3,3,2>();
+
+ test<4,4,0>();
+ test<4,4,1>();
+ test<4,4,2>();
+ test<4,4,3>();
+
+ test<5,5,0>();
+ test<5,5,1>();
+ test<5,5,2>();
+ test<5,5,3>();
+ test<5,5,4>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/del_row_col_test.cpp b/src/boost/libs/qvm/test/del_row_col_test.cpp
new file mode 100644
index 000000000..b07b15b48
--- /dev/null
+++ b/src/boost/libs/qvm/test/del_row_col_test.cpp
@@ -0,0 +1,101 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/map_mat_mat.hpp>
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/mat_traits_array.hpp>
+#include <boost/qvm/mat.hpp>
+#include "test_qvm.hpp"
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Rows,int Cols,int Row,int Col>
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ test_qvm::matrix<M1,Rows,Cols> x(42,1);
+ float r1[Rows-1][Cols-1];
+ for( int i=0; i!=Rows-1; ++i )
+ for( int j=0; j!=Cols-1; ++j )
+ r1[i][j]=x.a[i+(i>=Row)][j+(j>=Col)];
+ float r2[Rows-1][Cols-1];
+ assign(r2,del_row_col<Row,Col>(x));
+ BOOST_QVM_TEST_EQ(r1,r2);
+ del_row_col<Row,Col>(x) *= 2;
+ for( int i=0; i!=Rows-1; ++i )
+ for( int j=0; j!=Cols-1; ++j )
+ r1[i][j]=x.a[i+(i>=Row)][j+(j>=Col)];
+ assign(r2,del_row_col<Row,Col>(x));
+ BOOST_QVM_TEST_EQ(r1,r2);
+ del_row_col<Row,Col>(x) + del_row_col<Row,Col>(x);
+ -del_row_col<Row,Col>(x);
+ }
+ }
+
+int
+main()
+ {
+ test<2,2,0,0>();
+ test<2,2,0,1>();
+ test<2,2,1,0>();
+ test<2,2,1,1>();
+
+ test<3,3,0,0>();
+ test<3,3,0,1>();
+ test<3,3,0,2>();
+ test<3,3,1,0>();
+ test<3,3,1,1>();
+ test<3,3,1,2>();
+ test<3,3,2,0>();
+ test<3,3,2,1>();
+ test<3,3,2,2>();
+
+ test<4,4,0,0>();
+ test<4,4,0,1>();
+ test<4,4,0,2>();
+ test<4,4,0,3>();
+ test<4,4,1,0>();
+ test<4,4,1,1>();
+ test<4,4,1,2>();
+ test<4,4,1,3>();
+ test<4,4,2,0>();
+ test<4,4,2,1>();
+ test<4,4,2,2>();
+ test<4,4,2,3>();
+ test<4,4,3,0>();
+ test<4,4,3,1>();
+ test<4,4,3,2>();
+ test<4,4,3,3>();
+
+ test<5,5,0,0>();
+ test<5,5,0,1>();
+ test<5,5,0,2>();
+ test<5,5,0,3>();
+ test<5,5,0,4>();
+ test<5,5,1,0>();
+ test<5,5,1,1>();
+ test<5,5,1,2>();
+ test<5,5,1,3>();
+ test<5,5,1,4>();
+ test<5,5,2,0>();
+ test<5,5,2,1>();
+ test<5,5,2,2>();
+ test<5,5,2,3>();
+ test<5,5,2,4>();
+ test<5,5,3,0>();
+ test<5,5,3,1>();
+ test<5,5,3,2>();
+ test<5,5,3,3>();
+ test<5,5,3,4>();
+ test<5,5,4,0>();
+ test<5,5,4,1>();
+ test<5,5,4,2>();
+ test<5,5,4,3>();
+ test<5,5,4,4>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/del_row_test.cpp b/src/boost/libs/qvm/test/del_row_test.cpp
new file mode 100644
index 000000000..8ce14c5cf
--- /dev/null
+++ b/src/boost/libs/qvm/test/del_row_test.cpp
@@ -0,0 +1,61 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/map_mat_mat.hpp>
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/mat_traits_array.hpp>
+#include <boost/qvm/mat.hpp>
+#include "test_qvm.hpp"
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Rows,int Cols,int Row>
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ test_qvm::matrix<M1,Rows,Cols> x(42,1);
+ float r1[Rows-1][Cols];
+ for( int i=0; i!=Rows-1; ++i )
+ for( int j=0; j!=Cols; ++j )
+ r1[i][j]=x.a[i+(i>=Row)][j];
+ float r2[Rows-1][Cols];
+ assign(r2,del_row<Row>(x));
+ BOOST_QVM_TEST_EQ(r1,r2);
+ del_row<Row>(x) *= 2;
+ for( int i=0; i!=Rows-1; ++i )
+ for( int j=0; j!=Cols; ++j )
+ r1[i][j]=x.a[i+(i>=Row)][j];
+ assign(r2,del_row<Row>(x));
+ BOOST_QVM_TEST_EQ(r1,r2);
+ del_row<Row>(x)+del_row<Row>(x);
+ -del_row<Row>(x);
+ }
+ }
+
+int
+main()
+ {
+ test<2,2,0>();
+ test<2,2,1>();
+
+ test<3,3,0>();
+ test<3,3,1>();
+ test<3,3,2>();
+
+ test<4,4,0>();
+ test<4,4,1>();
+ test<4,4,2>();
+ test<4,4,3>();
+
+ test<5,5,0>();
+ test<5,5,1>();
+ test<5,5,2>();
+ test<5,5,3>();
+ test<5,5,4>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/determinant_test.cpp b/src/boost/libs/qvm/test/determinant_test.cpp
new file mode 100644
index 000000000..0a99aa09b
--- /dev/null
+++ b/src/boost/libs/qvm/test/determinant_test.cpp
@@ -0,0 +1,32 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/mat_operations.hpp>
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int D>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::matrix<M1,D,D> const x(42,1);
+ float gd=test_qvm::determinant(x.b);
+ float d=determinant(x);
+ BOOST_QVM_TEST_EQ(gd,d);
+ }
+ }
+
+int
+main()
+ {
+ test<2>();
+ test<3>();
+ test<4>();
+ test<5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/diag_mat_test.cpp b/src/boost/libs/qvm/test/diag_mat_test.cpp
new file mode 100644
index 000000000..75bdda5a9
--- /dev/null
+++ b/src/boost/libs/qvm/test/diag_mat_test.cpp
@@ -0,0 +1,42 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/map.hpp>
+#include <boost/qvm/mat_traits_array.hpp>
+#include <boost/qvm/vec_operations.hpp>
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/mat.hpp>
+#include "test_qvm_vector.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Dim>
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ test_qvm::vector<V1,Dim> x(42,1);
+ float y[Dim][Dim]; assign(y,diag_mat(x));
+ for( int i=0; i!=Dim; ++i )
+ x.b[i]=y[i][i];
+ BOOST_QVM_TEST_EQ(x.a,x.b);
+ test_qvm::scalar_multiply_v(x.b,x.a,2.0f);
+ diag(diag_mat(x)) *= 2;
+ BOOST_QVM_TEST_EQ(x.a,x.b);
+ diag_mat(x) + diag_mat(x);
+ -diag_mat(x);
+ }
+ }
+
+int
+main()
+ {
+ test<2>();
+ test<3>();
+ test<4>();
+ test<5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/diag_test.cpp b/src/boost/libs/qvm/test/diag_test.cpp
new file mode 100644
index 000000000..74626d0bf
--- /dev/null
+++ b/src/boost/libs/qvm/test/diag_test.cpp
@@ -0,0 +1,65 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_operations.hpp>
+#include <boost/qvm/vec.hpp>
+#include <boost/qvm/map_mat_vec.hpp>
+#include "test_qvm_matrix.hpp"
+#include "test_qvm_vector.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int A,int B,bool LessThan=(A<B)>
+ struct
+ get_min
+ {
+ static int const value=B;
+ };
+
+ template <int A,int B>
+ struct
+ get_min<A,B,true>
+ {
+ static int const value=A;
+ };
+
+ template <int Rows,int Cols>
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ int const D=get_min<Rows,Cols>::value;
+ test_qvm::matrix<M1,Rows,Cols> x(42,1);
+ test_qvm::vector<V1,D> y=diag(x);
+ for( int i=0; i!=D; ++i )
+ y.b[i]=x.a[i][i];
+ BOOST_QVM_TEST_EQ(y.a,y.b);
+ diag(x) *= 2;
+ for( int i=0; i!=D; ++i )
+ x.b[i][i] *= 2;
+ BOOST_QVM_TEST_EQ(x.a,x.b);
+ diag(x) + diag(x);
+ -diag(x);
+ }
+ }
+
+int
+main()
+ {
+ test<1,2>();
+ test<1,3>();
+ test<1,4>();
+ test<1,5>();
+ test<2,1>();
+ test<3,1>();
+ test<4,1>();
+ test<5,1>();
+ test<2,2>();
+ test<3,3>();
+ test<4,4>();
+ test<5,5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/div_eq_ms_test.cpp b/src/boost/libs/qvm/test/div_eq_ms_test.cpp
new file mode 100644
index 000000000..d532d8ff1
--- /dev/null
+++ b/src/boost/libs/qvm/test/div_eq_ms_test.cpp
@@ -0,0 +1,40 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/mat_operations.hpp>
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Rows,int Cols>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::matrix<M1,Rows,Cols> x(42,1);
+ test_qvm::scalar_multiply_m(x.b,x.a,0.5f);
+ x/=2;
+ BOOST_QVM_TEST_EQ(x.a,x.b);
+ }
+ }
+
+int
+main()
+ {
+ test<1,2>();
+ test<2,1>();
+ test<2,2>();
+ test<1,3>();
+ test<3,1>();
+ test<3,3>();
+ test<1,4>();
+ test<4,1>();
+ test<4,4>();
+ test<1,5>();
+ test<5,1>();
+ test<5,5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/div_eq_qs_test.cpp b/src/boost/libs/qvm/test/div_eq_qs_test.cpp
new file mode 100644
index 000000000..9412b360a
--- /dev/null
+++ b/src/boost/libs/qvm/test/div_eq_qs_test.cpp
@@ -0,0 +1,28 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/quat_operations.hpp>
+#include "test_qvm_quaternion.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::quaternion<Q1> x(42,1);
+ test_qvm::scalar_multiply_v(x.b,x.a,0.5f);
+ x/=2;
+ BOOST_QVM_TEST_EQ(x.a,x.b);
+ }
+ }
+
+int
+main()
+ {
+ test();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/div_eq_vs_test.cpp b/src/boost/libs/qvm/test/div_eq_vs_test.cpp
new file mode 100644
index 000000000..f767d4bc4
--- /dev/null
+++ b/src/boost/libs/qvm/test/div_eq_vs_test.cpp
@@ -0,0 +1,33 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_operations.hpp>
+#include "test_qvm_vector.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Dim>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::vector<V1,Dim> x(42,1);
+ test_qvm::scalar_multiply_v(x.b,x.a,0.5f);
+ x/=2;
+ BOOST_QVM_TEST_EQ(x.a,x.b);
+ }
+ }
+
+int
+main()
+ {
+ test<1>();
+ test<2>();
+ test<3>();
+ test<4>();
+ test<5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/div_ms_test.cpp b/src/boost/libs/qvm/test/div_ms_test.cpp
new file mode 100644
index 000000000..67875a518
--- /dev/null
+++ b/src/boost/libs/qvm/test/div_ms_test.cpp
@@ -0,0 +1,52 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/mat.hpp>
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <class T,class U> struct same_type_tester;
+ template <class T> struct same_type_tester<T,T> { };
+ template <class T,class U> void test_same_type( T, U ) { same_type_tester<T,U>(); }
+
+ template <int Rows,int Cols>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::matrix<M1,Rows,Cols> const x(42,1);
+ test_qvm::scalar_multiply_m(x.b,x.a,0.5f);
+ test_same_type(x,x/2);
+ {
+ test_qvm::matrix<M1,Rows,Cols> y=x/2;
+ BOOST_QVM_TEST_EQ(x.b,y.a);
+ }
+ {
+ test_qvm::matrix<M1,Rows,Cols> y=mref(x)/2;
+ BOOST_QVM_TEST_EQ(x.b,y.a);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test<1,2>();
+ test<2,1>();
+ test<2,2>();
+ test<1,3>();
+ test<3,1>();
+ test<3,3>();
+ test<1,4>();
+ test<4,1>();
+ test<4,4>();
+ test<1,5>();
+ test<5,1>();
+ test<5,5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/div_qs_test.cpp b/src/boost/libs/qvm/test/div_qs_test.cpp
new file mode 100644
index 000000000..1a2ff172c
--- /dev/null
+++ b/src/boost/libs/qvm/test/div_qs_test.cpp
@@ -0,0 +1,40 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/quat_operations.hpp>
+#include <boost/qvm/quat.hpp>
+#include "test_qvm_quaternion.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <class T,class U> struct same_type_tester;
+ template <class T> struct same_type_tester<T,T> { };
+ template <class T,class U> void test_same_type( T, U ) { same_type_tester<T,U>(); }
+
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::quaternion<Q1> const x(42,1);
+ test_qvm::scalar_multiply_v(x.b,x.a,0.5f);
+ test_same_type(x,x/2);
+ {
+ test_qvm::quaternion<Q1> y=x/2;
+ BOOST_QVM_TEST_EQ(x.b,y.a);
+ }
+ {
+ test_qvm::quaternion<Q1> y=qref(x)/2;
+ BOOST_QVM_TEST_EQ(x.b,y.a);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/div_vs_test.cpp b/src/boost/libs/qvm/test/div_vs_test.cpp
new file mode 100644
index 000000000..e17eb06ec
--- /dev/null
+++ b/src/boost/libs/qvm/test/div_vs_test.cpp
@@ -0,0 +1,45 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_operations.hpp>
+#include <boost/qvm/vec.hpp>
+#include "test_qvm_vector.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <class T,class U> struct same_type_tester;
+ template <class T> struct same_type_tester<T,T> { };
+ template <class T,class U> void test_same_type( T, U ) { same_type_tester<T,U>(); }
+
+ template <int Dim>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::vector<V1,Dim> const x(42,1);
+ test_qvm::scalar_multiply_v(x.b,x.a,0.5f);
+ test_same_type(x,x/2);
+ {
+ test_qvm::vector<V1,Dim> y=x/2;
+ BOOST_QVM_TEST_EQ(x.b,y.a);
+ }
+ {
+ test_qvm::vector<V1,Dim> y=vref(x)/2;
+ BOOST_QVM_TEST_EQ(x.b,y.a);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test<1>();
+ test<2>();
+ test<3>();
+ test<4>();
+ test<5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/dot_qq_test.cpp b/src/boost/libs/qvm/test/dot_qq_test.cpp
new file mode 100644
index 000000000..3c5a209b0
--- /dev/null
+++ b/src/boost/libs/qvm/test/dot_qq_test.cpp
@@ -0,0 +1,44 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/quat_operations.hpp>
+#include "test_qvm_quaternion.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <class T,class U> struct same_type_tester;
+ template <class T> struct same_type_tester<T,T> { };
+ template <class T,class U> void test_same_type( T, U ) { same_type_tester<T,U>(); }
+
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+
+ test_qvm::quaternion<Q1> const x(42,1);
+ {
+ test_qvm::quaternion<Q1> const y(43,1);
+ test_same_type(float(),dot(x,y));
+ float d1=dot(x,y);
+ float d2=test_qvm::dot<float>(x.a,y.a);
+ BOOST_QVM_TEST_CLOSE(d1,d2,0.000001f);
+ }
+ {
+ test_qvm::quaternion<Q1,double> const y(43,1);
+ test_same_type(double(),dot(x,y));
+ double d1=dot(x,y);
+ double d2=test_qvm::dot<double>(x.a,y.a);
+ BOOST_QVM_TEST_CLOSE(d1,d2,0.000001);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/dot_vv_test.cpp b/src/boost/libs/qvm/test/dot_vv_test.cpp
new file mode 100644
index 000000000..42f670ec3
--- /dev/null
+++ b/src/boost/libs/qvm/test/dot_vv_test.cpp
@@ -0,0 +1,48 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_operations.hpp>
+#include "test_qvm_vector.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <class T,class U> struct same_type_tester;
+ template <class T> struct same_type_tester<T,T> { };
+ template <class T,class U> void test_same_type( T, U ) { same_type_tester<T,U>(); }
+
+ template <int Dim>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+
+ test_qvm::vector<V1,Dim> const x(42,1);
+ {
+ test_qvm::vector<V1,Dim> const y(43,1);
+ test_same_type(float(),dot(x,y));
+ float d1=dot(x,y);
+ float d2=test_qvm::dot<float>(x.a,y.a);
+ BOOST_QVM_TEST_CLOSE(d1,d2,0.000001f);
+ }
+ {
+ test_qvm::vector<V1,Dim,double> const y(43,1);
+ test_same_type(double(),dot(x,y));
+ double d1=dot(x,y);
+ double d2=test_qvm::dot<double>(x.a,y.a);
+ BOOST_QVM_TEST_CLOSE(d1,d2,0.000001);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test<2>();
+ test<3>();
+ test<4>();
+ test<5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/eq_mm_test.cpp b/src/boost/libs/qvm/test/eq_mm_test.cpp
new file mode 100644
index 000000000..29c948d02
--- /dev/null
+++ b/src/boost/libs/qvm/test/eq_mm_test.cpp
@@ -0,0 +1,53 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/mat_operations.hpp>
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Rows,int Cols>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::matrix<M1,Rows,Cols> const x(42,1);
+ for( int i=0; i!=Rows; ++i )
+ for( int j=0; j!=Cols; ++j )
+ {
+ {
+ test_qvm::matrix<M1,Rows,Cols> y(x);
+ BOOST_QVM_TEST_EQ(x,y);
+ y.a[i][j]=0;
+ BOOST_QVM_TEST_NEQ(x,y);
+ }
+ {
+ test_qvm::matrix<M2,Rows,Cols> y; assign(y,x);
+ BOOST_QVM_TEST_EQ(x,y);
+ y.a[i][j]=0;
+ BOOST_QVM_TEST_NEQ(x,y);
+ }
+ }
+ }
+ }
+
+int
+main()
+ {
+ test<1,2>();
+ test<2,1>();
+ test<2,2>();
+ test<1,3>();
+ test<3,1>();
+ test<3,3>();
+ test<1,4>();
+ test<4,1>();
+ test<4,4>();
+ test<1,5>();
+ test<5,1>();
+ test<5,5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/eq_qq_test.cpp b/src/boost/libs/qvm/test/eq_qq_test.cpp
new file mode 100644
index 000000000..eb2eb4f9d
--- /dev/null
+++ b/src/boost/libs/qvm/test/eq_qq_test.cpp
@@ -0,0 +1,40 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Qersion 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/quat_operations.hpp>
+#include "test_qvm_quaternion.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::quaternion<Q1> const x(42,1);
+ for( int i=0; i!=4; ++i )
+ {
+ {
+ test_qvm::quaternion<Q1> y(x);
+ BOOST_QVM_TEST_EQ(x,y);
+ y.a[i]=0;
+ BOOST_QVM_TEST_NEQ(x,y);
+ }
+ {
+ test_qvm::quaternion<Q2> y; assign(y,x);
+ BOOST_QVM_TEST_EQ(x,y);
+ y.a[i]=0;
+ BOOST_QVM_TEST_NEQ(x,y);
+ }
+ }
+ }
+ }
+
+int
+main()
+ {
+ test();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/eq_vv_test.cpp b/src/boost/libs/qvm/test/eq_vv_test.cpp
new file mode 100644
index 000000000..5c556211a
--- /dev/null
+++ b/src/boost/libs/qvm/test/eq_vv_test.cpp
@@ -0,0 +1,44 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_operations.hpp>
+#include "test_qvm_vector.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Dim>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::vector<V1,Dim> const x(42,1);
+ for( int i=0; i!=Dim; ++i )
+ {
+ {
+ test_qvm::vector<V1,Dim> y(x);
+ BOOST_QVM_TEST_EQ(x,y);
+ y.a[i]=0;
+ BOOST_QVM_TEST_NEQ(x,y);
+ }
+ {
+ test_qvm::vector<V2,Dim> y; assign(y,x);
+ BOOST_QVM_TEST_EQ(x,y);
+ y.a[i]=0;
+ BOOST_QVM_TEST_NEQ(x,y);
+ }
+ }
+ }
+ }
+
+int
+main()
+ {
+ test<2>();
+ test<3>();
+ test<4>();
+ test<5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/gold.hpp b/src/boost/libs/qvm/test/gold.hpp
new file mode 100644
index 000000000..d55dba391
--- /dev/null
+++ b/src/boost/libs/qvm/test/gold.hpp
@@ -0,0 +1,439 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_QVM_907229FCB3A711DE83C152F855D89593
+#define BOOST_QVM_907229FCB3A711DE83C152F855D89593
+
+#include <limits>
+#include <math.h>
+#include <assert.h>
+#include <memory.h>
+#include <stdlib.h>
+
+namespace
+test_qvm
+ {
+ namespace
+ detail
+ {
+ inline
+ float
+ sin( float a )
+ {
+ return ::sinf(a);
+ }
+
+ inline
+ double
+ sin( double a )
+ {
+ return ::sin(a);
+ }
+
+ inline
+ float
+ cos( float a )
+ {
+ return ::cosf(a);
+ }
+
+ inline
+ double
+ cos( double a )
+ {
+ return ::cos(a);
+ }
+
+ inline
+ float
+ abs( float a )
+ {
+ return ::fabsf(a);
+ }
+
+ inline
+ double
+ abs( double a )
+ {
+ return ::fabs(a);
+ }
+
+ inline
+ float
+ atan2( float a, float b )
+ {
+ return ::atan2f(a,b);
+ }
+
+ inline
+ double
+ atan2( double a, double b )
+ {
+ return ::atan2(a,b);
+ }
+
+ template <class T>
+ T
+ determinant( T * * a, int n )
+ {
+ int i,j,j1,j2;
+ T det = 0;
+ T * * m = 0;
+ assert(n>=1);
+ if( n==1 )
+ det = a[0][0];
+ else if( n==2 )
+ det = a[0][0] * a[1][1] - a[1][0] * a[0][1];
+ else
+ {
+ det = 0;
+ for( j1=0; j1<n; j1++ )
+ {
+ m = static_cast<T * *>(malloc((n-1)*sizeof(T *)));
+ for( i=0; i<n-1; i++ )
+ m[i] = static_cast<T *>(malloc((n-1)*sizeof(T)));
+ for( i=1; i<n; i++ )
+ {
+ j2 = 0;
+ for( j=0; j<n; j++ )
+ {
+ if( j==j1 )
+ continue;
+ m[i-1][j2] = a[i][j];
+ j2++;
+ }
+ }
+ det += T(pow(-1.0,1.0+j1+1.0)) * a[0][j1] * determinant(m,n-1);
+ for( i=0; i<n-1; i++ )
+ free(m[i]);
+ free(m);
+ }
+ }
+ return(det);
+ }
+
+ template <class T,int N>
+ void
+ cofactor( T * * a, T (&b)[N][N] )
+ {
+ int i,j,ii,jj,i1,j1;
+ T det;
+ T * * c;
+ c = static_cast<T * *>(malloc((N-1)*sizeof(T *)));
+ for( i=0; i<N-1; i++ )
+ c[i] = static_cast<T *>(malloc((N-1)*sizeof(T)));
+ for( j=0; j<N; j++ )
+ {
+ for( i=0; i<N; i++ )
+ {
+ i1 = 0;
+ for( ii=0; ii<N; ii++ )
+ {
+ if( ii==i )
+ continue;
+ j1 = 0;
+ for( jj=0; jj<N; jj++ )
+ {
+ if( jj==j )
+ continue;
+ c[i1][j1] = a[ii][jj];
+ j1++;
+ }
+ i1++;
+ }
+ det = determinant(c,N-1);
+ b[i][j] = T(pow(-1.0,i+j+2.0)) * det;
+ }
+ }
+ for( i=0; i<N-1; i++ )
+ free(c[i]);
+ free(c);
+ }
+ }
+
+ template <class T,int D>
+ T
+ determinant( T (&in)[D][D] )
+ {
+ T * * m = static_cast<T * *>(malloc(D*sizeof(T *)));
+ for( int i=0; i!=D; ++i )
+ {
+ m[i] = static_cast<T *>(malloc(D*sizeof(T)));
+ for( int j=0; j!=D; ++j )
+ m[i][j]=in[i][j];
+ }
+ T det=::test_qvm::detail::determinant(m,D);
+ for( int i=0; i<D; ++i )
+ free(m[i]);
+ free(m);
+ return det;
+ }
+
+ template <class T,int D>
+ void
+ inverse( T (&out)[D][D], T (&in)[D][D] )
+ {
+ T * * m = static_cast<T * *>(malloc(D*sizeof(T *)));
+ for( int i=0; i!=D; ++i )
+ {
+ m[i] = static_cast<T *>(malloc(D*sizeof(T)));
+ for( int j=0; j!=D; ++j )
+ m[i][j]=in[i][j];
+ }
+ T det=::test_qvm::detail::determinant(m,D);
+ assert(det!=T(0));
+ T f=T(1)/det;
+ T b[D][D];
+ ::test_qvm::detail::cofactor(m,b);
+ for( int i=0; i<D; ++i )
+ free(m[i]);
+ free(m);
+ for( int i=0; i!=D; ++i )
+ for( int j=0; j!=D; ++j )
+ out[j][i]=b[i][j]*f;
+ }
+
+ template <class T,int M,int N>
+ void
+ init_m( T (&r)[M][N], T start=T(0), T step=T(0) )
+ {
+ for( int i=0; i<M; ++i )
+ for( int j=0; j<N; ++j,start+=step )
+ r[i][j] = start;
+ }
+
+ template <class T,int D>
+ void
+ init_v( T (&r)[D], T start=T(0), T step=T(0) )
+ {
+ for( int i=0; i<D; ++i,start+=step )
+ r[i] = start;
+ }
+
+ template <class T,int M,int N>
+ void
+ zero_mat( T (&r)[M][N] )
+ {
+ for( int i=0; i<M; ++i )
+ for( int j=0; j<N; ++j )
+ r[i][j] = T(0);
+ }
+
+ template <class T,int D>
+ void
+ zero_vec( T (&r)[D] )
+ {
+ for( int i=0; i<D; ++i )
+ r[i] = T(0);
+ }
+
+ template <class T,int D>
+ void
+ identity( T (&r)[D][D] )
+ {
+ for( int i=0; i<D; ++i )
+ for( int j=0; j<D; ++j )
+ r[i][j] = (i==j) ? T(1) : T(0);
+ }
+
+ template <class T,class U,class V,int M,int N>
+ void
+ add_m( T (&r)[M][N], U (&a)[M][N], V (&b)[M][N] )
+ {
+ for( int i=0; i<M; ++i )
+ for( int j=0; j<N; ++j )
+ r[i][j] = a[i][j] + b[i][j];
+ }
+
+ template <class T,class U,class V,int D>
+ void
+ add_v( T (&r)[D], U (&a)[D], V (&b)[D] )
+ {
+ for( int i=0; i<D; ++i )
+ r[i] = a[i] + b[i];
+ }
+
+ template <class T,class U,class V,int M,int N>
+ void
+ subtract_m( T (&r)[M][N], U (&a)[M][N], V (&b)[M][N] )
+ {
+ for( int i=0; i<M; ++i )
+ for( int j=0; j<N; ++j )
+ r[i][j] = a[i][j] - b[i][j];
+ }
+
+ template <class T,class U,class V,int D>
+ void
+ subtract_v( T (&r)[D], U (&a)[D], V (&b)[D] )
+ {
+ for( int i=0; i<D; ++i )
+ r[i] = a[i] - b[i];
+ }
+
+ template <class T,int D,class U>
+ void
+ rotation_x( T (&r)[D][D], U angle )
+ {
+ identity(r);
+ T c=::test_qvm::detail::cos(angle);
+ T s=::test_qvm::detail::sin(angle);
+ r[1][1]=c;
+ r[1][2]=-s;
+ r[2][1]=s;
+ r[2][2]=c;
+ }
+
+ template <class T,int D,class U>
+ void
+ rotation_y( T (&r)[D][D], U angle )
+ {
+ identity(r);
+ T c=::test_qvm::detail::cos(angle);
+ T s=::test_qvm::detail::sin(angle);
+ r[0][0]=c;
+ r[0][2]=s;
+ r[2][0]=-s;
+ r[2][2]=c;
+ }
+
+ template <class T,int D,class U>
+ void
+ rotation_z( T (&r)[D][D], U angle )
+ {
+ identity(r);
+ T c=::test_qvm::detail::cos(angle);
+ T s=::test_qvm::detail::sin(angle);
+ r[0][0]=c;
+ r[0][1]=-s;
+ r[1][0]=s;
+ r[1][1]=c;
+ }
+
+ template <class T,int D>
+ void
+ translation( T (&r)[D][D], T (&t)[D-1] )
+ {
+ identity(r);
+ for( int i=0; i!=D-1; ++i )
+ r[i][D-1]=t[i];
+ }
+
+ template <class R,class T,class U,int M,int N,int P>
+ void
+ multiply_m( R (&r)[M][P], T (&a)[M][N], U (&b)[N][P] )
+ {
+ for( int i=0; i<M; ++i )
+ for( int j=0; j<P; ++j )
+ {
+ R x=0;
+ for( int k=0; k<N; ++k )
+ x += R(a[i][k])*R(b[k][j]);
+ r[i][j] = x;
+ }
+ }
+
+ template <class R,class T,class U,int M,int N>
+ void
+ multiply_mv( R (&r)[M], T (&a)[M][N], U (&b)[N] )
+ {
+ for( int i=0; i<M; ++i )
+ {
+ R x=0;
+ for( int k=0; k<N; ++k )
+ x += R(a[i][k])*R(b[k]);
+ r[i] = x;
+ }
+ }
+
+ template <class R,class T,class U,int N,int P>
+ void
+ multiply_vm( R (&r)[P], T (&a)[N], U (&b)[N][P] )
+ {
+ for( int j=0; j<P; ++j )
+ {
+ R x=0;
+ for( int k=0; k<N; ++k )
+ x += R(a[k])*R(b[k][j]);
+ r[j] = x;
+ }
+ }
+
+ template <class T,class U,int M,int N,class S>
+ void
+ scalar_multiply_m( T (&r)[M][N], U (&a)[M][N], S scalar )
+ {
+ for( int i=0; i<M; ++i )
+ for( int j=0; j<N; ++j )
+ r[i][j] = a[i][j]*scalar;
+ }
+
+ template <class T,class U,int D,class S>
+ void
+ scalar_multiply_v( T (&r)[D], U (&a)[D], S scalar )
+ {
+ for( int i=0; i<D; ++i )
+ r[i] = a[i]*scalar;
+ }
+
+ template <class T,int M,int N>
+ void
+ transpose( T (&r)[M][N], T (&a)[N][M] )
+ {
+ for( int i=0; i<M; ++i )
+ for( int j=0; j<N; ++j )
+ r[i][j] = a[j][i];
+ }
+
+ template <class R,class T,class U,int D>
+ R
+ dot( T (&a)[D], U (&b)[D] )
+ {
+ R r=R(0);
+ for( int i=0; i<D; ++i )
+ r+=a[i]*b[i];
+ return r;
+ }
+
+ template <class T,int M,int N>
+ T
+ norm_squared( T (&m)[M][N] )
+ {
+ T f=T(0);
+ for( int i=0; i<M; ++i )
+ for( int j=0; j<N; ++j )
+ {
+ T x=m[i][j];
+ f+=x*x;
+ }
+ return f;
+ }
+
+ template <class T>
+ inline
+ void
+ matrix_perspective_lh( T (&r)[4][4], T fov_y, T aspect_ratio, T zn, T zf )
+ {
+ T ys=T(1)/::tanf(fov_y/T(2));
+ T xs=ys/aspect_ratio;
+ zero_mat(r);
+ r[0][0] = xs;
+ r[1][1] = ys;
+ r[2][2] = zf/(zf-zn);
+ r[2][3] = -zn*zf/(zf-zn);
+ r[3][2] = 1;
+ }
+
+ template <class T>
+ inline
+ void
+ matrix_perspective_rh( T (&r)[4][4], T fov_y, T aspect_ratio, T zn, T zf )
+ {
+ matrix_perspective_lh(r,fov_y,aspect_ratio,zn,zf);
+ r[2][2]=-r[2][2];
+ r[3][2]=-r[3][2];
+ }
+ }
+
+#endif
diff --git a/src/boost/libs/qvm/test/header-test.cpp b/src/boost/libs/qvm/test/header-test.cpp
new file mode 100644
index 000000000..db09236bd
--- /dev/null
+++ b/src/boost/libs/qvm/test/header-test.cpp
@@ -0,0 +1,7 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include REVERGE_HEADER
+#include REVERGE_HEADER
diff --git a/src/boost/libs/qvm/test/identity_mat_test.cpp b/src/boost/libs/qvm/test/identity_mat_test.cpp
new file mode 100644
index 000000000..ef753fb38
--- /dev/null
+++ b/src/boost/libs/qvm/test/identity_mat_test.cpp
@@ -0,0 +1,36 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/mat_operations.hpp>
+#include "test_qvm_matrix.hpp"
+
+namespace
+ {
+ template <int Dim>
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ test_qvm::matrix<M1,Dim,Dim> m=identity_mat<float,Dim>();
+ for( int i=0; i!=Dim; ++i )
+ for( int j=0; j!=Dim; ++j )
+ BOOST_TEST(m.a[i][j]==float(i==j));
+ test_qvm::matrix<M2,Dim,Dim> n(42,1);
+ set_identity(n);
+ for( int i=0; i!=Dim; ++i )
+ for( int j=0; j!=Dim; ++j )
+ BOOST_TEST(n.a[i][j]==float(i==j));
+ }
+ }
+
+int
+main()
+ {
+ test<2>();
+ test<3>();
+ test<4>();
+ test<5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/identity_quat_test.cpp b/src/boost/libs/qvm/test/identity_quat_test.cpp
new file mode 100644
index 000000000..d37288386
--- /dev/null
+++ b/src/boost/libs/qvm/test/identity_quat_test.cpp
@@ -0,0 +1,34 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/quat_operations.hpp>
+#include "test_qvm_quaternion.hpp"
+
+namespace
+ {
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ test_qvm::quaternion<Q1> q=identity_quat<float>();
+ BOOST_TEST(q.a[0]==1);
+ BOOST_TEST(q.a[1]==0);
+ BOOST_TEST(q.a[2]==0);
+ BOOST_TEST(q.a[3]==0);
+ test_qvm::quaternion<Q2> p(42,1);
+ set_identity(p);
+ BOOST_TEST(p.a[0]==1);
+ BOOST_TEST(p.a[1]==0);
+ BOOST_TEST(p.a[2]==0);
+ BOOST_TEST(p.a[3]==0);
+ }
+ }
+
+int
+main()
+ {
+ test();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/interop_test.cpp b/src/boost/libs/qvm/test/interop_test.cpp
new file mode 100644
index 000000000..37d67fc5a
--- /dev/null
+++ b/src/boost/libs/qvm/test/interop_test.cpp
@@ -0,0 +1,435 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/operations.hpp>
+#include <boost/qvm/quat.hpp>
+#include <boost/qvm/vec.hpp>
+#include <boost/qvm/mat.hpp>
+
+namespace
+my_stuff
+ {
+ struct
+ mat
+ {
+ float a[3][3];
+ };
+
+ struct
+ vec
+ {
+ float a[3];
+ };
+
+ struct
+ quat
+ {
+ float a[4];
+ };
+ }
+
+namespace
+boost
+ {
+ namespace
+ qvm
+ {
+ template <>
+ struct
+ mat_traits<my_stuff::mat>
+ {
+ typedef float scalar_type;
+ static int const rows=3;
+ static int const cols=3;
+
+ template <int R,int C>
+ static
+ scalar_type &
+ write_element( my_stuff::mat & m )
+ {
+ BOOST_QVM_STATIC_ASSERT(R>=0);
+ BOOST_QVM_STATIC_ASSERT(R<rows);
+ BOOST_QVM_STATIC_ASSERT(C>=0);
+ BOOST_QVM_STATIC_ASSERT(C<cols);
+ return m.a[R][C];
+ }
+
+ template <int R,int C>
+ static
+ scalar_type
+ read_element( my_stuff::mat const & m )
+ {
+ BOOST_QVM_STATIC_ASSERT(R>=0);
+ BOOST_QVM_STATIC_ASSERT(R<rows);
+ BOOST_QVM_STATIC_ASSERT(C>=0);
+ BOOST_QVM_STATIC_ASSERT(C<cols);
+ return m.a[R][C];
+ }
+
+ static
+ inline
+ scalar_type &
+ write_element_idx( int r, int c, my_stuff::mat & m )
+ {
+ BOOST_QVM_ASSERT(r>=0);
+ BOOST_QVM_ASSERT(r<rows);
+ BOOST_QVM_ASSERT(c>=0);
+ BOOST_QVM_ASSERT(c<cols);
+ return m.a[r][c];
+ }
+
+ static
+ inline
+ scalar_type
+ read_element_idx( int r, int c, my_stuff::mat const & m )
+ {
+ BOOST_QVM_ASSERT(r>=0);
+ BOOST_QVM_ASSERT(r<rows);
+ BOOST_QVM_ASSERT(c>=0);
+ BOOST_QVM_ASSERT(c<cols);
+ return m.a[r][c];
+ }
+ };
+
+ template <>
+ struct
+ vec_traits<my_stuff::vec>
+ {
+ static int const dim=3;
+ typedef float scalar_type;
+
+ template <int I>
+ static
+ scalar_type &
+ write_element( my_stuff::vec & m )
+ {
+ BOOST_QVM_STATIC_ASSERT(I>=0);
+ BOOST_QVM_STATIC_ASSERT(I<dim);
+ return m.a[I];
+ }
+
+ template <int I>
+ static
+ scalar_type
+ read_element( my_stuff::vec const & m )
+ {
+ BOOST_QVM_STATIC_ASSERT(I>=0);
+ BOOST_QVM_STATIC_ASSERT(I<dim);
+ return m.a[I];
+ }
+
+ static
+ inline
+ scalar_type &
+ write_element_idx( int i, my_stuff::vec & m )
+ {
+ BOOST_QVM_ASSERT(i>=0);
+ BOOST_QVM_ASSERT(i<dim);
+ return m.a[i];
+ }
+
+ static
+ inline
+ scalar_type
+ read_element_idx( int i, my_stuff::vec const & m )
+ {
+ BOOST_QVM_ASSERT(i>=0);
+ BOOST_QVM_ASSERT(i<dim);
+ return m.a[i];
+ }
+ };
+
+ template <>
+ struct
+ quat_traits<my_stuff::quat>
+ {
+ typedef float scalar_type;
+
+ template <int I>
+ static
+ scalar_type &
+ write_element( my_stuff::quat & m )
+ {
+ BOOST_QVM_STATIC_ASSERT(I>=0);
+ BOOST_QVM_STATIC_ASSERT(I<4);
+ return m.a[I];
+ }
+
+ template <int I>
+ static
+ scalar_type
+ read_element( my_stuff::quat const & m )
+ {
+ BOOST_QVM_STATIC_ASSERT(I>=0);
+ BOOST_QVM_STATIC_ASSERT(I<4);
+ return m.a[I];
+ }
+ };
+ }
+ }
+
+namespace
+my_stuff
+ {
+ mat &
+ operator/=( mat & x, float y )
+ {
+ return boost::qvm::operator/=(x,y);
+ }
+
+ vec &
+ operator/=( vec & x, float y )
+ {
+ return boost::qvm::operator/=(x,y);
+ }
+
+ quat &
+ operator/=( quat & x, float y )
+ {
+ return boost::qvm::operator/=(x,y);
+ }
+
+ mat &
+ operator*=( mat & x, float y )
+ {
+ return boost::qvm::operator*=(x,y);
+ }
+
+ vec &
+ operator*=( vec & x, float y )
+ {
+ return boost::qvm::operator*=(x,y);
+ }
+
+ quat &
+ operator*=( quat & x, float y )
+ {
+ return boost::qvm::operator*=(x,y);
+ }
+
+ mat
+ operator/( mat const & x, float y )
+ {
+ return boost::qvm::operator/(x,y);
+ }
+
+ vec
+ operator/( vec const & x, float y )
+ {
+ return boost::qvm::operator/(x,y);
+ }
+
+ quat
+ operator/( quat const & x, float y )
+ {
+ return boost::qvm::operator/(x,y);
+ }
+
+ mat
+ operator*( mat const & x, float y )
+ {
+ return boost::qvm::operator*(x,y);
+ }
+
+ vec
+ operator*( vec const & x, float y )
+ {
+ return boost::qvm::operator*(x,y);
+ }
+
+ quat
+ operator*( quat const & x, float y )
+ {
+ return boost::qvm::operator*(x,y);
+ }
+
+ mat &
+ operator*=( mat & x, mat const & y )
+ {
+ return boost::qvm::operator*=(x,y);
+ }
+
+ mat
+ operator*=( mat const & x, mat const & y )
+ {
+ return boost::qvm::operator*(x,y);
+ }
+
+ vec
+ operator*( mat const & x, vec const & y )
+ {
+ return boost::qvm::operator*(x,y);
+ }
+
+ vec
+ operator*( quat const & x, vec const & y )
+ {
+ return boost::qvm::operator*(x,y);
+ }
+
+ vec
+ operator*( vec const & x, mat const & y )
+ {
+ return boost::qvm::operator*(x,y);
+ }
+
+ bool
+ operator==( mat const & x, mat const & y )
+ {
+ return boost::qvm::operator==(x,y);
+ }
+
+ bool
+ operator!=( mat const & x, mat const & y )
+ {
+ return boost::qvm::operator!=(x,y);
+ }
+
+ bool
+ operator==( vec const & x, vec const & y )
+ {
+ return boost::qvm::operator==(x,y);
+ }
+
+ bool
+ operator!=( vec const & x, vec const & y )
+ {
+ return boost::qvm::operator!=(x,y);
+ }
+
+ bool
+ operator==( quat const & x, quat const & y )
+ {
+ return boost::qvm::operator==(x,y);
+ }
+
+ bool
+ operator!=( quat const & x, quat const & y )
+ {
+ return boost::qvm::operator!=(x,y);
+ }
+ }
+
+int
+main()
+ {
+ using namespace boost::qvm::sfinae;
+ using namespace my_stuff;
+ typedef boost::qvm::mat<double,3,3> mat2;
+ typedef boost::qvm::vec<double,3> vec2;
+ typedef boost::qvm::quat<double> quat2;
+
+ mat ma1, mb1; set_zero(ma1); set_zero(mb1);
+ vec va1, vb1; set_zero(va1); set_zero(vb1);
+ quat qa1, qb1; set_zero(qa1); set_zero(qb1);
+ mat2 ma2, mb2; set_zero(ma2); set_zero(mb2);
+ vec2 va2, vb2; set_zero(va2); set_zero(vb2);
+ quat2 qa2, qb2; set_zero(qa2); set_zero(qb2);
+
+ set_zero(ma1);
+ set_zero(mb1);
+ set_zero(va1);
+ set_zero(vb1);
+ set_zero(qa1);
+ set_zero(qb1);
+ set_zero(ma2);
+ set_zero(mb2);
+ set_zero(va2);
+ set_zero(vb2);
+ set_zero(qa2);
+ set_zero(qb2);
+
+ ma1/=2;
+ va1/=2;
+ qa1/=2;
+ ma2/=2;
+ va2/=2;
+ qa2/=2;
+
+ ma1*=2;
+ va1*=2;
+ qa1*=2;
+ ma2*=2;
+ va2*=2;
+ qa2*=2;
+
+ mb1=ma1/2;
+ vb1=va1/2;
+ qb1=qb1/2;
+ mb2=convert_to<mat2>(ma1/2);
+ vb2=convert_to<vec2>(va1/2);
+ qb2=convert_to<quat2>(qa1/2);
+ mb1=scalar_cast<float>(ma2/2);
+ vb1=scalar_cast<float>(va2/2);
+ qb1=scalar_cast<float>(qa2/2);
+
+ mb1=ma1*2;
+ vb1=va1*2;
+ qb1=qa1*2;
+ mb2=convert_to<mat2>(ma1*2);
+ vb2=convert_to<vec2>(va1*2);
+ qb2=convert_to<quat2>(qa1*2);
+ mb1=scalar_cast<float>(ma2*2);
+ vb1=scalar_cast<float>(va2*2);
+ qb1=scalar_cast<float>(qa2*2);
+
+ ma1*=mb1;
+ ma1*=scalar_cast<float>(ma2);
+ ma2*=ma1;
+
+ va1=ma1*va1;
+ va1=qa1*va1;
+ va1=scalar_cast<float>(ma2*va1);
+ va1=scalar_cast<float>(ma1*va2);
+ va1=scalar_cast<float>(ma2*va2);
+ va1=scalar_cast<float>(qa2*va1);
+ va1=scalar_cast<float>(qa1*va2);
+ va1=scalar_cast<float>(qa2*va2);
+
+ va2=convert_to<vec2>(ma1*va1);
+ va2=convert_to<vec2>(qa1*va1);
+ va2=ma2*va1;
+ va2=ma1*va2;
+ va2=ma2*va2;
+ va2=qa2*va1;
+ va2=qa1*va2;
+ va2=qa2*va2;
+
+ va1=va1*ma1;
+ va1=scalar_cast<float>(va1*ma2);
+ va1=scalar_cast<float>(va2*ma1);
+ va1=scalar_cast<float>(va2*ma2);
+
+ va2=convert_to<vec2>(va1*ma1);
+ va2=va1*ma2;
+ va2=va2*ma1;
+ va2=va2*ma2;
+
+ (void) (ma1==mb1);
+ (void) (ma1==ma2);
+ (void) (ma2==ma1);
+
+ (void) (ma1!=mb1);
+ (void) (ma1!=ma2);
+ (void) (ma2!=ma1);
+
+ (void) (va1==vb1);
+ (void) (va1==va2);
+ (void) (va2==va1);
+
+ (void) (va1!=vb1);
+ (void) (va1!=va2);
+ (void) (va2!=va1);
+
+ (void) (qa1==qb1);
+ (void) (qa1==qa2);
+ (void) (qa2==qa1);
+
+ (void) (qa1!=qb1);
+ (void) (qa1!=qa2);
+ (void) (qa2!=qa1);
+
+ return 0;
+ }
diff --git a/src/boost/libs/qvm/test/inverse_m_test.cpp b/src/boost/libs/qvm/test/inverse_m_test.cpp
new file mode 100644
index 000000000..5c2754ddd
--- /dev/null
+++ b/src/boost/libs/qvm/test/inverse_m_test.cpp
@@ -0,0 +1,55 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/mat.hpp>
+#include <boost/exception/diagnostic_information.hpp>
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <class T,class U> struct same_type_tester;
+ template <class T> struct same_type_tester<T,T> { };
+ template <class T,class U> void test_same_type( T, U ) { same_type_tester<T,U>(); }
+
+ template <int D>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::matrix<M1,D,D> x;
+ test_qvm::rotation_z(x.a,42.0f);
+ test_qvm::inverse(x.b,x.a);
+ test_same_type(x,inverse(x));
+ {
+ test_qvm::matrix<M1,D,D> y=inverse(x);
+ BOOST_QVM_TEST_CLOSE(x.b,y.a,0.000001f);
+ }
+ {
+ test_qvm::matrix<M1,D,D> y=inverse(mref(x));
+ BOOST_QVM_TEST_CLOSE(x.b,y.a,0.000001f);
+ }
+ }
+ }
+
+int
+main()
+ {
+ try
+ {
+ test<2>();
+ test<3>();
+ test<4>();
+ test<5>();
+ return boost::report_errors();
+ }
+ catch(
+ ... )
+ {
+ std::cerr << "Uncaught exception:\n" << boost::current_exception_diagnostic_information();
+ return 1;
+ }
+ }
diff --git a/src/boost/libs/qvm/test/inverse_q_test.cpp b/src/boost/libs/qvm/test/inverse_q_test.cpp
new file mode 100644
index 000000000..52bf2c00e
--- /dev/null
+++ b/src/boost/libs/qvm/test/inverse_q_test.cpp
@@ -0,0 +1,41 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/quat_operations.hpp>
+#include <boost/qvm/quat.hpp>
+#include <boost/exception/diagnostic_information.hpp>
+#include "test_qvm_quaternion.hpp"
+#include "test_qvm.hpp"
+
+namespace
+ {
+ template <class T,class U> struct same_type_tester;
+ template <class T> struct same_type_tester<T,T> { };
+ template <class T,class U> void test_same_type( T, U ) { same_type_tester<T,U>(); }
+
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ test_qvm::quaternion<Q1> x=rotx_quat(4.2f);
+ test_same_type(x,inverse(x));
+ test_qvm::quaternion<Q1> y=rotx_quat(-4.2f);
+ {
+ test_qvm::quaternion<Q1> z=inverse(x);
+ BOOST_QVM_TEST_CLOSE_QUAT(z.a,y.a,0.00001f);
+ }
+ {
+ test_qvm::quaternion<Q1> z=inverse(qref(x));
+ BOOST_QVM_TEST_CLOSE_QUAT(z.a,y.a,0.00001f);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/mag_q_test.cpp b/src/boost/libs/qvm/test/mag_q_test.cpp
new file mode 100644
index 000000000..96669e9c1
--- /dev/null
+++ b/src/boost/libs/qvm/test/mag_q_test.cpp
@@ -0,0 +1,31 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/quat_operations.hpp>
+#include "test_qvm_quaternion.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+
+ test_qvm::quaternion<Q1> const x(42,1);
+ float m1=mag(x);
+ float m2=mag(qref(x));
+ float m3=sqrtf(test_qvm::dot<float>(x.a,x.a));
+ BOOST_QVM_TEST_CLOSE(m1,m3,0.000001f);
+ BOOST_QVM_TEST_CLOSE(m2,m3,0.000001f);
+ }
+ }
+
+int
+main()
+ {
+ test();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/mag_sqr_q_test.cpp b/src/boost/libs/qvm/test/mag_sqr_q_test.cpp
new file mode 100644
index 000000000..9fab3e15a
--- /dev/null
+++ b/src/boost/libs/qvm/test/mag_sqr_q_test.cpp
@@ -0,0 +1,30 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/quat_operations.hpp>
+#include "test_qvm_quaternion.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::quaternion<Q1> const x(42,1);
+ float m1=mag_sqr(x);
+ float m2=mag_sqr(qref(x));
+ float m3=test_qvm::dot<float>(x.a,x.a);
+ BOOST_QVM_TEST_CLOSE(m1,m3,0.000001f);
+ BOOST_QVM_TEST_CLOSE(m2,m3,0.000001f);
+ }
+ }
+
+int
+main()
+ {
+ test();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/mag_sqr_v_test.cpp b/src/boost/libs/qvm/test/mag_sqr_v_test.cpp
new file mode 100644
index 000000000..ea3166589
--- /dev/null
+++ b/src/boost/libs/qvm/test/mag_sqr_v_test.cpp
@@ -0,0 +1,35 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_operations.hpp>
+#include "test_qvm_vector.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Dim>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+
+ test_qvm::vector<V1,Dim> const x(42,1);
+ float m1=mag_sqr(x);
+ float m2=mag_sqr(vref(x));
+ float m3=test_qvm::dot<float>(x.a,x.a);
+ BOOST_QVM_TEST_CLOSE(m1,m3,0.000001f);
+ BOOST_QVM_TEST_CLOSE(m2,m3,0.000001f);
+ }
+ }
+
+int
+main()
+ {
+ test<2>();
+ test<3>();
+ test<4>();
+ test<5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/mag_v_test.cpp b/src/boost/libs/qvm/test/mag_v_test.cpp
new file mode 100644
index 000000000..f9b816f8a
--- /dev/null
+++ b/src/boost/libs/qvm/test/mag_v_test.cpp
@@ -0,0 +1,35 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_operations.hpp>
+#include "test_qvm_vector.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Dim>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+
+ test_qvm::vector<V1,Dim> const x(42,1);
+ float m1=mag(x);
+ float m2=mag(vref(x));
+ float m3=sqrtf(test_qvm::dot<float>(x.a,x.a));
+ BOOST_QVM_TEST_CLOSE(m1,m3,0.000001f);
+ BOOST_QVM_TEST_CLOSE(m2,m3,0.000001f);
+ }
+ }
+
+int
+main()
+ {
+ test<2>();
+ test<3>();
+ test<4>();
+ test<5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/mat_index_test.cpp b/src/boost/libs/qvm/test/mat_index_test.cpp
new file mode 100644
index 000000000..34515ad1a
--- /dev/null
+++ b/src/boost/libs/qvm/test/mat_index_test.cpp
@@ -0,0 +1,34 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include "test_qvm_matrix.hpp"
+
+int
+main()
+ {
+ using namespace boost::qvm;
+
+ typedef test_qvm::matrix<M1,2,3> M;
+ M m;
+ m.a[0][0]=42.0f;
+ m.a[0][1]=43.0f;
+ m.a[0][2]=44.0f;
+ m.a[1][0]=45.0f;
+ m.a[1][1]=46.0f;
+ m.a[1][2]=47.0f;
+ BOOST_TEST(mat_traits<M>::read_element_idx(0,0,m)==m.a[0][0]);
+ BOOST_TEST(mat_traits<M>::read_element_idx(0,1,m)==m.a[0][1]);
+ BOOST_TEST(mat_traits<M>::read_element_idx(0,2,m)==m.a[0][2]);
+ BOOST_TEST(mat_traits<M>::read_element_idx(1,0,m)==m.a[1][0]);
+ BOOST_TEST(mat_traits<M>::read_element_idx(1,1,m)==m.a[1][1]);
+ BOOST_TEST(mat_traits<M>::read_element_idx(1,2,m)==m.a[1][2]);
+ BOOST_TEST(&mat_traits<M>::write_element_idx(0,0,m)==&m.a[0][0]);
+ BOOST_TEST(&mat_traits<M>::write_element_idx(0,1,m)==&m.a[0][1]);
+ BOOST_TEST(&mat_traits<M>::write_element_idx(0,2,m)==&m.a[0][2]);
+ BOOST_TEST(&mat_traits<M>::write_element_idx(1,0,m)==&m.a[1][0]);
+ BOOST_TEST(&mat_traits<M>::write_element_idx(1,1,m)==&m.a[1][1]);
+ BOOST_TEST(&mat_traits<M>::write_element_idx(1,2,m)==&m.a[1][2]);
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/mat_traits_array_test.cpp b/src/boost/libs/qvm/test/mat_traits_array_test.cpp
new file mode 100644
index 000000000..8db70605a
--- /dev/null
+++ b/src/boost/libs/qvm/test/mat_traits_array_test.cpp
@@ -0,0 +1,136 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/mat_traits_array.hpp>
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+template <class T,class U>
+struct same_type;
+
+template <class T>
+struct
+same_type<T,T>
+ {
+ };
+
+template <class T,class P>
+void
+test_ref_cast( T & v, P * ptr )
+ {
+ using namespace boost::qvm;
+ BOOST_QVM_STATIC_ASSERT(is_mat<T>::value);
+ BOOST_QVM_STATIC_ASSERT(mat_traits<T>::rows==3);
+ BOOST_QVM_STATIC_ASSERT(mat_traits<T>::cols==2);
+ BOOST_TEST((mat_traits<T>::template read_element<0,0>(v)==ptr[0*2+0]));
+ BOOST_TEST((mat_traits<T>::template read_element<0,1>(v)==ptr[0*2+1]));
+ BOOST_TEST((mat_traits<T>::template read_element<1,0>(v)==ptr[1*2+0]));
+ BOOST_TEST((mat_traits<T>::template read_element<1,1>(v)==ptr[1*2+1]));
+ BOOST_TEST((mat_traits<T>::template read_element<2,0>(v)==ptr[2*2+0]));
+ BOOST_TEST((mat_traits<T>::template read_element<2,1>(v)==ptr[2*2+1]));
+ BOOST_TEST((&mat_traits<T>::template write_element<0,0>(v)==&ptr[0*2+0]));
+ BOOST_TEST((&mat_traits<T>::template write_element<0,1>(v)==&ptr[0*2+1]));
+ BOOST_TEST((&mat_traits<T>::template write_element<1,0>(v)==&ptr[1*2+0]));
+ BOOST_TEST((&mat_traits<T>::template write_element<1,1>(v)==&ptr[1*2+1]));
+ BOOST_TEST((&mat_traits<T>::template write_element<2,0>(v)==&ptr[2*2+0]));
+ BOOST_TEST((&mat_traits<T>::template write_element<2,1>(v)==&ptr[2*2+1]));
+ BOOST_TEST(&v[0][0]==&ptr[0*2+0]);
+ BOOST_TEST(&v[0][1]==&ptr[0*2+1]);
+ BOOST_TEST(&v[1][0]==&ptr[1*2+0]);
+ BOOST_TEST(&v[1][1]==&ptr[1*2+1]);
+ BOOST_TEST(&v[2][0]==&ptr[2*2+0]);
+ BOOST_TEST(&v[2][1]==&ptr[2*2+1]);
+ }
+
+int
+main()
+ {
+ using namespace boost::qvm;
+ {
+ BOOST_QVM_STATIC_ASSERT(!is_mat<int[3]>::value);
+ BOOST_QVM_STATIC_ASSERT(!is_mat<int[3][3][3]>::value);
+ BOOST_QVM_STATIC_ASSERT(is_mat<int[3][4]>::value);
+ BOOST_QVM_STATIC_ASSERT(mat_traits<int[3][4]>::rows==3);
+ BOOST_QVM_STATIC_ASSERT(mat_traits<int[3][4]>::cols==4);
+ same_type<mat_traits<int[3][4]>::scalar_type,int>();
+ same_type< mat<int,3,3>, deduce_mat<int[3][3]>::type >();
+ same_type< mat<int,3,3>, deduce_mat<int const[3][3]>::type >();
+ int arr[3][3] = {{00,01,02},{10,11,12},{20,21,22}};
+ BOOST_TEST((mat_traits<int[3][3]>::read_element<0,0>(arr)==00));
+ BOOST_TEST((mat_traits<int[3][3]>::read_element<0,1>(arr)==01));
+ BOOST_TEST((mat_traits<int[3][3]>::read_element<0,2>(arr)==02));
+ BOOST_TEST((mat_traits<int[3][3]>::read_element<1,0>(arr)==10));
+ BOOST_TEST((mat_traits<int[3][3]>::read_element<1,1>(arr)==11));
+ BOOST_TEST((mat_traits<int[3][3]>::read_element<1,2>(arr)==12));
+ BOOST_TEST((mat_traits<int[3][3]>::read_element<2,0>(arr)==20));
+ BOOST_TEST((mat_traits<int[3][3]>::read_element<2,1>(arr)==21));
+ BOOST_TEST((mat_traits<int[3][3]>::read_element<2,2>(arr)==22));
+ BOOST_TEST((mat_traits<int const[3][3]>::read_element<0,0>(arr)==00));
+ BOOST_TEST((mat_traits<int const[3][3]>::read_element<0,1>(arr)==01));
+ BOOST_TEST((mat_traits<int const[3][3]>::read_element<0,2>(arr)==02));
+ BOOST_TEST((mat_traits<int const[3][3]>::read_element<1,0>(arr)==10));
+ BOOST_TEST((mat_traits<int const[3][3]>::read_element<1,1>(arr)==11));
+ BOOST_TEST((mat_traits<int const[3][3]>::read_element<1,2>(arr)==12));
+ BOOST_TEST((mat_traits<int const[3][3]>::read_element<2,0>(arr)==20));
+ BOOST_TEST((mat_traits<int const[3][3]>::read_element<2,1>(arr)==21));
+ BOOST_TEST((mat_traits<int const[3][3]>::read_element<2,2>(arr)==22));
+ BOOST_TEST((mat_traits<int[3][3]>::read_element_idx(0,0,arr)==00));
+ BOOST_TEST((mat_traits<int[3][3]>::read_element_idx(0,1,arr)==01));
+ BOOST_TEST((mat_traits<int[3][3]>::read_element_idx(0,2,arr)==02));
+ BOOST_TEST((mat_traits<int[3][3]>::read_element_idx(1,0,arr)==10));
+ BOOST_TEST((mat_traits<int[3][3]>::read_element_idx(1,1,arr)==11));
+ BOOST_TEST((mat_traits<int[3][3]>::read_element_idx(1,2,arr)==12));
+ BOOST_TEST((mat_traits<int[3][3]>::read_element_idx(2,0,arr)==20));
+ BOOST_TEST((mat_traits<int[3][3]>::read_element_idx(2,1,arr)==21));
+ BOOST_TEST((mat_traits<int[3][3]>::read_element_idx(2,2,arr)==22));
+ BOOST_TEST((mat_traits<int const[3][3]>::read_element_idx(0,0,arr)==00));
+ BOOST_TEST((mat_traits<int const[3][3]>::read_element_idx(0,1,arr)==01));
+ BOOST_TEST((mat_traits<int const[3][3]>::read_element_idx(0,2,arr)==02));
+ BOOST_TEST((mat_traits<int const[3][3]>::read_element_idx(1,0,arr)==10));
+ BOOST_TEST((mat_traits<int const[3][3]>::read_element_idx(1,1,arr)==11));
+ BOOST_TEST((mat_traits<int const[3][3]>::read_element_idx(1,2,arr)==12));
+ BOOST_TEST((mat_traits<int const[3][3]>::read_element_idx(2,0,arr)==20));
+ BOOST_TEST((mat_traits<int const[3][3]>::read_element_idx(2,1,arr)==21));
+ BOOST_TEST((mat_traits<int const[3][3]>::read_element_idx(2,2,arr)==22));
+ BOOST_TEST((&mat_traits<int[3][3]>::write_element<0,0>(arr)==&arr[0][0]));
+ BOOST_TEST((&mat_traits<int[3][3]>::write_element<0,1>(arr)==&arr[0][1]));
+ BOOST_TEST((&mat_traits<int[3][3]>::write_element<0,2>(arr)==&arr[0][2]));
+ BOOST_TEST((&mat_traits<int[3][3]>::write_element<1,0>(arr)==&arr[1][0]));
+ BOOST_TEST((&mat_traits<int[3][3]>::write_element<1,1>(arr)==&arr[1][1]));
+ BOOST_TEST((&mat_traits<int[3][3]>::write_element<1,2>(arr)==&arr[1][2]));
+ BOOST_TEST((&mat_traits<int[3][3]>::write_element<2,0>(arr)==&arr[2][0]));
+ BOOST_TEST((&mat_traits<int[3][3]>::write_element<2,1>(arr)==&arr[2][1]));
+ BOOST_TEST((&mat_traits<int[3][3]>::write_element<2,2>(arr)==&arr[2][2]));
+ BOOST_TEST((&mat_traits<int[3][3]>::write_element_idx(0,0,arr)==&arr[0][0]));
+ BOOST_TEST((&mat_traits<int[3][3]>::write_element_idx(0,1,arr)==&arr[0][1]));
+ BOOST_TEST((&mat_traits<int[3][3]>::write_element_idx(0,2,arr)==&arr[0][2]));
+ BOOST_TEST((&mat_traits<int[3][3]>::write_element_idx(1,0,arr)==&arr[1][0]));
+ BOOST_TEST((&mat_traits<int[3][3]>::write_element_idx(1,1,arr)==&arr[1][1]));
+ BOOST_TEST((&mat_traits<int[3][3]>::write_element_idx(1,2,arr)==&arr[1][2]));
+ BOOST_TEST((&mat_traits<int[3][3]>::write_element_idx(2,0,arr)==&arr[2][0]));
+ BOOST_TEST((&mat_traits<int[3][3]>::write_element_idx(2,1,arr)==&arr[2][1]));
+ BOOST_TEST((&mat_traits<int[3][3]>::write_element_idx(2,2,arr)==&arr[2][2]));
+ }
+ {
+ int arr[42] = {0};
+ int * ptr=arr+5;
+ ptr[0*2+0]=42;
+ ptr[0*2+1]=43;
+ ptr[1*2+0]=44;
+ ptr[1*2+1]=45;
+ ptr[2*2+0]=46;
+ ptr[2*2+1]=47;
+ test_ref_cast(ptr_mref<3,2>(ptr),ptr);
+ int m[3][2] = {{1,1},{1,1},{1,1}};
+ ptr_mref<3,2>(ptr) += mref(m);
+ BOOST_TEST(ptr[0*2+0]=43);
+ BOOST_TEST(ptr[0*2+1]=44);
+ BOOST_TEST(ptr[1*2+0]=45);
+ BOOST_TEST(ptr[1*2+1]=46);
+ BOOST_TEST(ptr[2*2+0]=47);
+ BOOST_TEST(ptr[2*2+1]=48);
+ }
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/math_test.cpp b/src/boost/libs/qvm/test/math_test.cpp
new file mode 100644
index 000000000..10e4a0345
--- /dev/null
+++ b/src/boost/libs/qvm/test/math_test.cpp
@@ -0,0 +1,102 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/math.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <stdlib.h>
+
+namespace
+ {
+ template <class T>
+ void
+ test1( T (*f1)(T), T (*f2)(T) )
+ {
+ for( int i=0; i!=100; ++i )
+ {
+ T a = T(rand()) / T(RAND_MAX);
+ BOOST_TEST_EQ(f1(a), f2(a));
+ }
+ }
+ template <class T,class U>
+ void
+ test2( T (*f1)(T,U), T (*f2)(T,U) )
+ {
+ for( int i=0; i!=100; ++i )
+ {
+ T a = T(rand()) / T(RAND_MAX);
+ T b = T(rand()) / T(RAND_MAX);
+ BOOST_TEST_EQ(f1(a,b), f2(a,b));
+ }
+ }
+ }
+
+int
+main()
+ {
+ test1<float>(&boost::qvm::acos<float>, &::acosf);
+ test1<float>(&boost::qvm::asin<float>, &::asinf);
+ test1<float>(&boost::qvm::atan<float>, &::atanf);
+ test2<float,float>(&boost::qvm::atan2<float>, &::atan2f);
+ test1<float>(&boost::qvm::cos<float>, &::cosf);
+ test1<float>(&boost::qvm::sin<float>, &::sinf);
+ test1<float>(&boost::qvm::tan<float>, &::tanf);
+ test1<float>(&boost::qvm::cosh<float>, &::coshf);
+ test1<float>(&boost::qvm::sinh<float>, &::sinhf);
+ test1<float>(&boost::qvm::tanh<float>, &::tanhf);
+ test1<float>(&boost::qvm::exp<float>, &::expf);
+ test1<float>(&boost::qvm::log<float>, &::logf);
+ test1<float>(&boost::qvm::log10<float>, &::log10f);
+ test2<float,float>(&boost::qvm::mod<float>, &::fmodf);
+ test2<float,float>(&boost::qvm::pow<float>, &::powf);
+ test1<float>(&boost::qvm::sqrt<float>, &::sqrtf);
+ test1<float>(&boost::qvm::ceil<float>, &::ceilf);
+ test1<float>(&boost::qvm::abs<float>, &::fabsf);
+ test1<float>(&boost::qvm::floor<float>, &::floorf);
+ test2<float, int>(&boost::qvm::ldexp<float>, &::ldexpf);
+
+ test1<double>(&boost::qvm::acos<double>, &::acos);
+ test1<double>(&boost::qvm::asin<double>, &::asin);
+ test1<double>(&boost::qvm::atan<double>, &::atan);
+ test2<double,double>(&boost::qvm::atan2<double>, &::atan2);
+ test1<double>(&boost::qvm::cos<double>, &::cos);
+ test1<double>(&boost::qvm::sin<double>, &::sin);
+ test1<double>(&boost::qvm::tan<double>, &::tan);
+ test1<double>(&boost::qvm::cosh<double>, &::cosh);
+ test1<double>(&boost::qvm::sinh<double>, &::sinh);
+ test1<double>(&boost::qvm::tanh<double>, &::tanh);
+ test1<double>(&boost::qvm::exp<double>, &::exp);
+ test1<double>(&boost::qvm::log<double>, &::log);
+ test1<double>(&boost::qvm::log10<double>, &::log10);
+ test2<double,double>(&boost::qvm::mod<double>, &::fmod);
+ test2<double,double>(&boost::qvm::pow<double>, &::pow);
+ test1<double>(&boost::qvm::sqrt<double>, &::sqrt);
+ test1<double>(&boost::qvm::ceil<double>, &::ceil);
+ test1<double>(&boost::qvm::abs<double>, &::fabs);
+ test1<double>(&boost::qvm::floor<double>, &::floor);
+ test2<double, int>(&boost::qvm::ldexp<double>, &::ldexp);
+
+ test1<long double>(&boost::qvm::acos<long double>, &::acosl);
+ test1<long double>(&boost::qvm::asin<long double>, &::asinl);
+ test1<long double>(&boost::qvm::atan<long double>, &::atanl);
+ test2<long double,long double>(&boost::qvm::atan2<long double>, &::atan2l);
+ test1<long double>(&boost::qvm::cos<long double>, &::cosl);
+ test1<long double>(&boost::qvm::sin<long double>, &::sinl);
+ test1<long double>(&boost::qvm::tan<long double>, &::tanl);
+ test1<long double>(&boost::qvm::cosh<long double>, &::coshl);
+ test1<long double>(&boost::qvm::sinh<long double>, &::sinhl);
+ test1<long double>(&boost::qvm::tanh<long double>, &::tanhl);
+ test1<long double>(&boost::qvm::exp<long double>, &::expl);
+ test1<long double>(&boost::qvm::log<long double>, &::logl);
+ test1<long double>(&boost::qvm::log10<long double>, &::log10l);
+ test2<long double,long double>(&boost::qvm::mod<long double>, &::fmodl);
+ test2<long double,long double>(&boost::qvm::pow<long double>, &::powl);
+ test1<long double>(&boost::qvm::sqrt<long double>, &::sqrtl);
+ test1<long double>(&boost::qvm::ceil<long double>, &::ceill);
+ test1<long double>(&boost::qvm::abs<long double>, &::fabsl);
+ test1<long double>(&boost::qvm::floor<long double>, &::floorl);
+ test2<long double, int>(&boost::qvm::ldexp<long double>, &::ldexpl);
+
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/minus_eq_mm_test.cpp b/src/boost/libs/qvm/test/minus_eq_mm_test.cpp
new file mode 100644
index 000000000..d5906bfcc
--- /dev/null
+++ b/src/boost/libs/qvm/test/minus_eq_mm_test.cpp
@@ -0,0 +1,49 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/mat_operations.hpp>
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Rows,int Cols>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::matrix<M1,Rows,Cols> x(42,2);
+ {
+ test_qvm::matrix<M1,Rows,Cols> const y(42,1);
+ test_qvm::subtract_m(x.b,x.a,y.a);
+ x-=y;
+ BOOST_QVM_TEST_EQ(x.a,x.b);
+ }
+ {
+ test_qvm::matrix<M2,Rows,Cols> const y(42,1);
+ test_qvm::subtract_m(x.b,x.a,y.a);
+ x-=y;
+ BOOST_QVM_TEST_EQ(x.a,x.b);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test<1,2>();
+ test<2,1>();
+ test<2,2>();
+ test<1,3>();
+ test<3,1>();
+ test<3,3>();
+ test<1,4>();
+ test<4,1>();
+ test<4,4>();
+ test<1,5>();
+ test<5,1>();
+ test<5,5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/minus_eq_qq_test.cpp b/src/boost/libs/qvm/test/minus_eq_qq_test.cpp
new file mode 100644
index 000000000..81dafee0b
--- /dev/null
+++ b/src/boost/libs/qvm/test/minus_eq_qq_test.cpp
@@ -0,0 +1,37 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/quat_operations.hpp>
+#include "test_qvm_quaternion.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::quaternion<Q1> x(42,2);
+ {
+ test_qvm::quaternion<Q1> const y(42,1);
+ test_qvm::subtract_v(x.b,x.a,y.a);
+ x-=y;
+ BOOST_QVM_TEST_EQ(x.a,x.b);
+ }
+ {
+ test_qvm::quaternion<Q2> const y(42,1);
+ test_qvm::subtract_v(x.b,x.a,y.a);
+ x-=y;
+ BOOST_QVM_TEST_EQ(x.a,x.b);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/minus_eq_vv_test.cpp b/src/boost/libs/qvm/test/minus_eq_vv_test.cpp
new file mode 100644
index 000000000..9b28bba6a
--- /dev/null
+++ b/src/boost/libs/qvm/test/minus_eq_vv_test.cpp
@@ -0,0 +1,41 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_operations.hpp>
+#include "test_qvm_vector.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Dim>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::vector<V1,Dim> x(42,2);
+ {
+ test_qvm::vector<V1,Dim> const y(42,1);
+ test_qvm::subtract_v(x.b,x.a,y.a);
+ x-=y;
+ BOOST_QVM_TEST_EQ(x.a,x.b);
+ }
+ {
+ test_qvm::vector<V2,Dim> const y(42,1);
+ test_qvm::subtract_v(x.b,x.a,y.a);
+ x-=y;
+ BOOST_QVM_TEST_EQ(x.a,x.b);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test<2>();
+ test<3>();
+ test<4>();
+ test<5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/minus_m_test.cpp b/src/boost/libs/qvm/test/minus_m_test.cpp
new file mode 100644
index 000000000..62ca0dd56
--- /dev/null
+++ b/src/boost/libs/qvm/test/minus_m_test.cpp
@@ -0,0 +1,52 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/mat.hpp>
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <class T,class U> struct same_type_tester;
+ template <class T> struct same_type_tester<T,T> { };
+ template <class T,class U> void test_same_type( T, U ) { same_type_tester<T,U>(); }
+
+ template <int Rows,int Cols>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::matrix<M1,Rows,Cols> const x(42,1);
+ test_qvm::scalar_multiply_m(x.b,x.a,-1.0f);
+ test_same_type(x,-x);
+ {
+ test_qvm::matrix<M1,Rows,Cols> y=-x;
+ BOOST_QVM_TEST_EQ(x.b,y.a);
+ }
+ {
+ test_qvm::matrix<M1,Rows,Cols> y=-mref(x);
+ BOOST_QVM_TEST_EQ(x.b,y.a);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test<1,2>();
+ test<2,1>();
+ test<2,2>();
+ test<1,3>();
+ test<3,1>();
+ test<3,3>();
+ test<1,4>();
+ test<4,1>();
+ test<4,4>();
+ test<1,5>();
+ test<5,1>();
+ test<5,5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/minus_mm_test.cpp b/src/boost/libs/qvm/test/minus_mm_test.cpp
new file mode 100644
index 000000000..fbe8a1c9d
--- /dev/null
+++ b/src/boost/libs/qvm/test/minus_mm_test.cpp
@@ -0,0 +1,61 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/mat.hpp>
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <class T,class U> struct same_type_tester;
+ template <class T> struct same_type_tester<T,T> { };
+ template <class T,class U> void test_same_type( T, U ) { same_type_tester<T,U>(); }
+
+ template <int Rows,int Cols>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::matrix<M1,Rows,Cols> const x(42,2);
+ {
+ test_qvm::matrix<M1,Rows,Cols> const y(42,1);
+ test_same_type(x,x-y);
+ test_qvm::matrix<M1,Rows,Cols> r=x-y;
+ test_qvm::subtract_m(r.b,x.b,y.b);
+ BOOST_QVM_TEST_EQ(r.a,r.b);
+ }
+ {
+ test_qvm::matrix<M1,Rows,Cols> const y(42,1);
+ test_qvm::matrix<M2,Rows,Cols> r=mref(x)-y;
+ test_qvm::subtract_m(r.b,x.b,y.b);
+ BOOST_QVM_TEST_EQ(r.a,r.b);
+ }
+ {
+ test_qvm::matrix<M1,Rows,Cols> const y(42,1);
+ test_qvm::matrix<M2,Rows,Cols> r=x-mref(y);
+ test_qvm::subtract_m(r.b,x.b,y.b);
+ BOOST_QVM_TEST_EQ(r.a,r.b);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test<1,2>();
+ test<2,1>();
+ test<2,2>();
+ test<1,3>();
+ test<3,1>();
+ test<3,3>();
+ test<1,4>();
+ test<4,1>();
+ test<4,4>();
+ test<1,5>();
+ test<5,1>();
+ test<5,5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/minus_q_test.cpp b/src/boost/libs/qvm/test/minus_q_test.cpp
new file mode 100644
index 000000000..845a0bbfa
--- /dev/null
+++ b/src/boost/libs/qvm/test/minus_q_test.cpp
@@ -0,0 +1,40 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/quat_operations.hpp>
+#include <boost/qvm/quat.hpp>
+#include "test_qvm_quaternion.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <class T,class U> struct same_type_tester;
+ template <class T> struct same_type_tester<T,T> { };
+ template <class T,class U> void test_same_type( T, U ) { same_type_tester<T,U>(); }
+
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::quaternion<Q1> const x(42,1);
+ test_qvm::scalar_multiply_v(x.b,x.a,-1.0f);
+ test_same_type(x,-x);
+ {
+ test_qvm::quaternion<Q1> y=-x;
+ BOOST_QVM_TEST_EQ(x.b,y.a);
+ }
+ {
+ test_qvm::quaternion<Q1> y=-qref(x);
+ BOOST_QVM_TEST_EQ(x.b,y.a);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/minus_qq_test.cpp b/src/boost/libs/qvm/test/minus_qq_test.cpp
new file mode 100644
index 000000000..ee37c0c23
--- /dev/null
+++ b/src/boost/libs/qvm/test/minus_qq_test.cpp
@@ -0,0 +1,49 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/quat_operations.hpp>
+#include <boost/qvm/quat.hpp>
+#include "test_qvm_quaternion.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <class T,class U> struct same_type_tester;
+ template <class T> struct same_type_tester<T,T> { };
+ template <class T,class U> void test_same_type( T, U ) { same_type_tester<T,U>(); }
+
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::quaternion<Q1> const x(42,2);
+ {
+ test_qvm::quaternion<Q1> const y(42,1);
+ test_same_type(x,x-y);
+ test_qvm::quaternion<Q1> r=x-y;
+ test_qvm::subtract_v(r.b,x.b,y.b);
+ BOOST_QVM_TEST_EQ(r.a,r.b);
+ }
+ {
+ test_qvm::quaternion<Q1> const y(42,1);
+ test_qvm::quaternion<Q2> r=qref(x)-y;
+ test_qvm::subtract_v(r.b,x.b,y.b);
+ BOOST_QVM_TEST_EQ(r.a,r.b);
+ }
+ {
+ test_qvm::quaternion<Q1> const y(42,1);
+ test_qvm::quaternion<Q2> r=x-qref(y);
+ test_qvm::subtract_v(r.b,x.b,y.b);
+ BOOST_QVM_TEST_EQ(r.a,r.b);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/minus_v_test.cpp b/src/boost/libs/qvm/test/minus_v_test.cpp
new file mode 100644
index 000000000..9a5c99025
--- /dev/null
+++ b/src/boost/libs/qvm/test/minus_v_test.cpp
@@ -0,0 +1,44 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_operations.hpp>
+#include <boost/qvm/vec.hpp>
+#include "test_qvm_vector.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <class T,class U> struct same_type_tester;
+ template <class T> struct same_type_tester<T,T> { };
+ template <class T,class U> void test_same_type( T, U ) { same_type_tester<T,U>(); }
+
+ template <int Dim>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::vector<V1,Dim> const x(42,1);
+ test_qvm::scalar_multiply_v(x.b,x.a,-1.0f);
+ test_same_type(x,-x);
+ {
+ test_qvm::vector<V1,Dim> y=-x;
+ BOOST_QVM_TEST_EQ(x.b,y.a);
+ }
+ {
+ test_qvm::vector<V1,Dim> y=-vref(x);
+ BOOST_QVM_TEST_EQ(x.b,y.a);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test<2>();
+ test<3>();
+ test<4>();
+ test<5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/minus_vv_test.cpp b/src/boost/libs/qvm/test/minus_vv_test.cpp
new file mode 100644
index 000000000..0d09a4f55
--- /dev/null
+++ b/src/boost/libs/qvm/test/minus_vv_test.cpp
@@ -0,0 +1,53 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_operations.hpp>
+#include <boost/qvm/vec.hpp>
+#include "test_qvm_vector.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <class T,class U> struct same_type_tester;
+ template <class T> struct same_type_tester<T,T> { };
+ template <class T,class U> void test_same_type( T, U ) { same_type_tester<T,U>(); }
+
+ template <int Dim>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::vector<V1,Dim> const x(42,2);
+ {
+ test_qvm::vector<V1,Dim> const y(42,1);
+ test_same_type(x,x-y);
+ test_qvm::vector<V1,Dim> r=x-y;
+ test_qvm::subtract_v(r.b,x.b,y.b);
+ BOOST_QVM_TEST_EQ(r.a,r.b);
+ }
+ {
+ test_qvm::vector<V1,Dim> const y(42,1);
+ test_qvm::vector<V2,Dim> r=vref(x)-y;
+ test_qvm::subtract_v(r.b,x.b,y.b);
+ BOOST_QVM_TEST_EQ(r.a,r.b);
+ }
+ {
+ test_qvm::vector<V1,Dim> const y(42,1);
+ test_qvm::vector<V2,Dim> r=x-vref(y);
+ test_qvm::subtract_v(r.b,x.b,y.b);
+ BOOST_QVM_TEST_EQ(r.a,r.b);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test<2>();
+ test<3>();
+ test<4>();
+ test<5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/mul_eq_mm_test.cpp b/src/boost/libs/qvm/test/mul_eq_mm_test.cpp
new file mode 100644
index 000000000..5c78e29f8
--- /dev/null
+++ b/src/boost/libs/qvm/test/mul_eq_mm_test.cpp
@@ -0,0 +1,42 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/mat_operations.hpp>
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Dim>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ {
+ test_qvm::matrix<M1,Dim,Dim> x(42,1);
+ test_qvm::matrix<M1,Dim,Dim> const y(42,2);
+ test_qvm::multiply_m(x.b,x.a,y.a);
+ x *= y;
+ BOOST_QVM_TEST_EQ(x.a,x.b);
+ }
+ {
+ test_qvm::matrix<M1,Dim,Dim> x(42,1);
+ test_qvm::matrix<M2,Dim,Dim> const y(42,2);
+ test_qvm::multiply_m(x.b,x.a,y.a);
+ x *= y;
+ BOOST_QVM_TEST_EQ(x.a,x.b);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test<2>();
+ test<3>();
+ test<4>();
+ test<5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/mul_eq_ms_test.cpp b/src/boost/libs/qvm/test/mul_eq_ms_test.cpp
new file mode 100644
index 000000000..11776de4e
--- /dev/null
+++ b/src/boost/libs/qvm/test/mul_eq_ms_test.cpp
@@ -0,0 +1,40 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/mat_operations.hpp>
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Rows,int Cols>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::matrix<M1,Rows,Cols> x(42,1);
+ test_qvm::scalar_multiply_m(x.b,x.a,2.0f);
+ x*=2;
+ BOOST_QVM_TEST_EQ(x.a,x.b);
+ }
+ }
+
+int
+main()
+ {
+ test<1,2>();
+ test<2,1>();
+ test<2,2>();
+ test<1,3>();
+ test<3,1>();
+ test<3,3>();
+ test<1,4>();
+ test<4,1>();
+ test<4,4>();
+ test<1,5>();
+ test<5,1>();
+ test<5,5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/mul_eq_qq_test.cpp b/src/boost/libs/qvm/test/mul_eq_qq_test.cpp
new file mode 100644
index 000000000..1c1d814fd
--- /dev/null
+++ b/src/boost/libs/qvm/test/mul_eq_qq_test.cpp
@@ -0,0 +1,46 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/quat_operations.hpp>
+#include <boost/qvm/mat_operations.hpp>
+#include "test_qvm_quaternion.hpp"
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <class T,class U> struct same_type_tester;
+ template <class T> struct same_type_tester<T,T> { };
+ template <class T,class U> void test_same_type( T, U ) { same_type_tester<T,U>(); }
+
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ for( float a=0; a<6.28f; a+=0.2f )
+ {
+ test_qvm::quaternion<Q1> const qx=rotx_quat(a);
+ test_qvm::quaternion<Q1> const qy=roty_quat(a);
+ test_qvm::quaternion<Q1> const qz=rotz_quat(a);
+ test_qvm::quaternion<Q1> q1=identity_quat<float>();
+ q1 *= qx;
+ q1 *= qy;
+ q1 *= qref(qz);
+ test_qvm::matrix<M1,3,3> const mx=rotx_mat<3>(a);
+ test_qvm::matrix<M1,3,3> const my=roty_mat<3>(a);
+ test_qvm::matrix<M1,3,3> const mz=rotz_mat<3>(a);
+ test_qvm::matrix<M1,3,3> const m=mx*my*mz;
+ test_qvm::quaternion<Q1> const q2=convert_to< test_qvm::quaternion<Q1> >(m);
+ BOOST_QVM_TEST_CLOSE_QUAT(q1.a,q2.a,0.00001f);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/mul_eq_qs_test.cpp b/src/boost/libs/qvm/test/mul_eq_qs_test.cpp
new file mode 100644
index 000000000..1d3e3d527
--- /dev/null
+++ b/src/boost/libs/qvm/test/mul_eq_qs_test.cpp
@@ -0,0 +1,28 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/quat_operations.hpp>
+#include "test_qvm_quaternion.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::quaternion<Q1> x(42,1);
+ test_qvm::scalar_multiply_v(x.b,x.a,2);
+ x*=2;
+ BOOST_QVM_TEST_EQ(x.a,x.b);
+ }
+ }
+
+int
+main()
+ {
+ test();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/mul_eq_vs_test.cpp b/src/boost/libs/qvm/test/mul_eq_vs_test.cpp
new file mode 100644
index 000000000..56da18c75
--- /dev/null
+++ b/src/boost/libs/qvm/test/mul_eq_vs_test.cpp
@@ -0,0 +1,33 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_operations.hpp>
+#include "test_qvm_vector.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Dim>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::vector<V1,Dim> x(42,1);
+ test_qvm::scalar_multiply_v(x.b,x.a,2.0f);
+ x*=2;
+ BOOST_QVM_TEST_EQ(x.a,x.b);
+ }
+ }
+
+int
+main()
+ {
+ test<1>();
+ test<2>();
+ test<3>();
+ test<4>();
+ test<5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/mul_mm_test.cpp b/src/boost/libs/qvm/test/mul_mm_test.cpp
new file mode 100644
index 000000000..2df4deada
--- /dev/null
+++ b/src/boost/libs/qvm/test/mul_mm_test.cpp
@@ -0,0 +1,55 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/mat.hpp>
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int R,int Q,int C>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::matrix<M1,R,Q> const x(42,1);
+ test_qvm::matrix<M2,Q,C> const y(42,1);
+ {
+ test_qvm::matrix<M3,R,C> r=x*y;
+ test_qvm::multiply_m(r.b,x.b,y.b);
+ BOOST_QVM_TEST_CLOSE(r.a,r.b,0.0000001f);
+ }
+ {
+ test_qvm::matrix<M3,R,C> r=mref(x)*y;
+ test_qvm::multiply_m(r.b,x.b,y.b);
+ BOOST_QVM_TEST_CLOSE(r.a,r.b,0.0000001f);
+ }
+ {
+ test_qvm::matrix<M3,R,C> r=x*mref(y);
+ test_qvm::multiply_m(r.b,x.b,y.b);
+ BOOST_QVM_TEST_CLOSE(r.a,r.b,0.0000001f);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test<1,2,2>();
+ test<2,2,1>();
+ test<2,2,2>();
+ test<1,3,3>();
+ test<3,3,1>();
+ test<3,3,3>();
+ test<1,4,4>();
+ test<4,4,1>();
+ test<4,4,4>();
+ test<1,5,5>();
+ test<5,5,1>();
+ test<5,5,5>();
+ test<2,3,4>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/mul_ms_test.cpp b/src/boost/libs/qvm/test/mul_ms_test.cpp
new file mode 100644
index 000000000..642b2732a
--- /dev/null
+++ b/src/boost/libs/qvm/test/mul_ms_test.cpp
@@ -0,0 +1,52 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/mat.hpp>
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <class T,class U> struct same_type_tester;
+ template <class T> struct same_type_tester<T,T> { };
+ template <class T,class U> void test_same_type( T, U ) { same_type_tester<T,U>(); }
+
+ template <int Rows,int Cols>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::matrix<M1,Rows,Cols> const x(42,1);
+ test_qvm::scalar_multiply_m(x.b,x.a,2.0f);
+ test_same_type(x,x*2);
+ {
+ test_qvm::matrix<M1,Rows,Cols> y=x*2;
+ BOOST_QVM_TEST_EQ(x.b,y.a);
+ }
+ {
+ test_qvm::matrix<M1,Rows,Cols> y=mref(x)*2;
+ BOOST_QVM_TEST_EQ(x.b,y.a);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test<1,2>();
+ test<2,1>();
+ test<2,2>();
+ test<1,3>();
+ test<3,1>();
+ test<3,3>();
+ test<1,4>();
+ test<4,1>();
+ test<4,4>();
+ test<1,5>();
+ test<5,1>();
+ test<5,5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/mul_mv_test.cpp b/src/boost/libs/qvm/test/mul_mv_test.cpp
new file mode 100644
index 000000000..368116d2c
--- /dev/null
+++ b/src/boost/libs/qvm/test/mul_mv_test.cpp
@@ -0,0 +1,75 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_mat_operations.hpp>
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/vec_operations.hpp>
+#include <boost/qvm/mat.hpp>
+#include <boost/qvm/vec.hpp>
+#include "test_qvm_matrix.hpp"
+#include "test_qvm_vector.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <class T,class U>
+ struct same_type;
+
+ template <class T>
+ struct
+ same_type<T,T>
+ {
+ };
+
+ template <class T,class U>
+ void
+ check_same_type( T const &, U const & )
+ {
+ same_type<T,U>();
+ }
+
+ template <int M,int N>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::matrix<M1,M,N> const x(42,1);
+ test_qvm::vector<V1,N> const y(42,1);
+ {
+ test_qvm::vector<V2,M> r=x*y;
+ test_qvm::multiply_mv(r.b,x.b,y.b);
+ BOOST_QVM_TEST_CLOSE(r.a,r.b,0.0000001f);
+ }
+ {
+ test_qvm::vector<V2,M> r=mref(x)*y;
+ test_qvm::multiply_mv(r.b,x.b,y.b);
+ BOOST_QVM_TEST_CLOSE(r.a,r.b,0.0000001f);
+ }
+ {
+ test_qvm::vector<V2,M> r=x*vref(y);
+ test_qvm::multiply_mv(r.b,x.b,y.b);
+ BOOST_QVM_TEST_CLOSE(r.a,r.b,0.0000001f);
+ }
+ check_same_type(x*y,boost::qvm::vec<float,M>());
+ }
+ }
+
+int
+main()
+ {
+ test<1,2>();
+ test<2,1>();
+ test<2,2>();
+ test<1,3>();
+ test<3,1>();
+ test<3,3>();
+ test<1,4>();
+ test<4,1>();
+ test<4,4>();
+ test<1,5>();
+ test<5,1>();
+ test<5,5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/mul_qq_test.cpp b/src/boost/libs/qvm/test/mul_qq_test.cpp
new file mode 100644
index 000000000..7b45ce408
--- /dev/null
+++ b/src/boost/libs/qvm/test/mul_qq_test.cpp
@@ -0,0 +1,45 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/quat_operations.hpp>
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/quat.hpp>
+#include "test_qvm_quaternion.hpp"
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <class T,class U> struct same_type_tester;
+ template <class T> struct same_type_tester<T,T> { };
+ template <class T,class U> void test_same_type( T, U ) { same_type_tester<T,U>(); }
+
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ for( float a=0; a<6.28f; a+=0.2f )
+ {
+ test_qvm::quaternion<Q1> const qx=rotx_quat(a);
+ test_qvm::quaternion<Q1> const qy=roty_quat(a);
+ test_qvm::quaternion<Q1> const qz=rotz_quat(a);
+ test_qvm::quaternion<Q1> const q1=qx*qy*qref(qz);
+ test_qvm::matrix<M1,3,3> const mx=rotx_mat<3>(a);
+ test_qvm::matrix<M1,3,3> const my=roty_mat<3>(a);
+ test_qvm::matrix<M1,3,3> const mz=rotz_mat<3>(a);
+ test_qvm::matrix<M1,3,3> const m=mx*my*mz;
+ test_qvm::quaternion<Q1> const q2=convert_to< test_qvm::quaternion<Q1> >(m);
+ test_same_type(qx,qx*qy);
+ BOOST_QVM_TEST_CLOSE_QUAT(q1.a,q2.a,0.00001f);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/mul_qs_test.cpp b/src/boost/libs/qvm/test/mul_qs_test.cpp
new file mode 100644
index 000000000..89089df9a
--- /dev/null
+++ b/src/boost/libs/qvm/test/mul_qs_test.cpp
@@ -0,0 +1,40 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/quat_operations.hpp>
+#include <boost/qvm/quat.hpp>
+#include "test_qvm_quaternion.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <class T,class U> struct same_type_tester;
+ template <class T> struct same_type_tester<T,T> { };
+ template <class T,class U> void test_same_type( T, U ) { same_type_tester<T,U>(); }
+
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::quaternion<Q1> const x(42,1);
+ test_qvm::scalar_multiply_v(x.b,x.a,2);
+ test_same_type(x,x*2);
+ {
+ test_qvm::quaternion<Q1> y=x*2;
+ BOOST_QVM_TEST_EQ(x.b,y.a);
+ }
+ {
+ test_qvm::quaternion<Q1> y=qref(x)*2;
+ BOOST_QVM_TEST_EQ(x.b,y.a);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/mul_qv_test.cpp b/src/boost/libs/qvm/test/mul_qv_test.cpp
new file mode 100644
index 000000000..403d45d2e
--- /dev/null
+++ b/src/boost/libs/qvm/test/mul_qv_test.cpp
@@ -0,0 +1,51 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/operations.hpp>
+#include <boost/qvm/vec.hpp>
+#include "test_qvm_quaternion.hpp"
+#include "test_qvm_matrix.hpp"
+#include "test_qvm_vector.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <class T,class U> struct same_type_tester;
+ template <class T> struct same_type_tester<T,T> { };
+ template <class T,class U> void test_same_type( T, U ) { same_type_tester<T,U>(); }
+
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ for( float a=0; a<6.28f; a+=0.2f )
+ {
+ test_qvm::quaternion<Q1> const qx=rotx_quat(a);
+ test_qvm::quaternion<Q1> const qy=roty_quat(a);
+ test_qvm::quaternion<Q1> const qz=rotz_quat(a);
+ test_qvm::matrix<M1,3,3> const mx=rotx_mat<3>(a);
+ test_qvm::matrix<M1,3,3> const my=roty_mat<3>(a);
+ test_qvm::matrix<M1,3,3> const mz=rotz_mat<3>(a);
+ test_qvm::vector<V1,3> const v(42,1);
+ test_same_type(vec<float,3>(),qx*v);
+ test_qvm::vector<V1,3> const q_vx=qx*v;
+ test_qvm::vector<V1,3> const m_vx=mx*v;
+ test_qvm::vector<V1,3> const q_vy=qy*v;
+ test_qvm::vector<V1,3> const m_vy=my*v;
+ test_qvm::vector<V1,3> const q_vz=qz*v;
+ test_qvm::vector<V1,3> const m_vz=mz*v;
+ BOOST_QVM_TEST_CLOSE(q_vx.a,m_vx.a,0.001f);
+ BOOST_QVM_TEST_CLOSE(q_vy.a,m_vy.a,0.001f);
+ BOOST_QVM_TEST_CLOSE(q_vz.a,m_vz.a,0.001f);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/mul_sm_test.cpp b/src/boost/libs/qvm/test/mul_sm_test.cpp
new file mode 100644
index 000000000..1de3a7526
--- /dev/null
+++ b/src/boost/libs/qvm/test/mul_sm_test.cpp
@@ -0,0 +1,52 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/mat.hpp>
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <class T,class U> struct same_type_tester;
+ template <class T> struct same_type_tester<T,T> { };
+ template <class T,class U> void test_same_type( T, U ) { same_type_tester<T,U>(); }
+
+ template <int Rows,int Cols>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::matrix<M1,Rows,Cols> const x(42,1);
+ test_qvm::scalar_multiply_m(x.b,x.a,2.0f);
+ test_same_type(x,2*x);
+ {
+ test_qvm::matrix<M1,Rows,Cols> y=2*x;
+ BOOST_QVM_TEST_EQ(x.b,y.a);
+ }
+ {
+ test_qvm::matrix<M1,Rows,Cols> y=2*mref(x);
+ BOOST_QVM_TEST_EQ(x.b,y.a);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test<1,2>();
+ test<2,1>();
+ test<2,2>();
+ test<1,3>();
+ test<3,1>();
+ test<3,3>();
+ test<1,4>();
+ test<4,1>();
+ test<4,4>();
+ test<1,5>();
+ test<5,1>();
+ test<5,5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/mul_sv_test.cpp b/src/boost/libs/qvm/test/mul_sv_test.cpp
new file mode 100644
index 000000000..009f29a03
--- /dev/null
+++ b/src/boost/libs/qvm/test/mul_sv_test.cpp
@@ -0,0 +1,45 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_operations.hpp>
+#include <boost/qvm/vec.hpp>
+#include "test_qvm_vector.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <class T,class U> struct same_type_tester;
+ template <class T> struct same_type_tester<T,T> { };
+ template <class T,class U> void test_same_type( T, U ) { same_type_tester<T,U>(); }
+
+ template <int Dim>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::vector<V1,Dim> const x(42,1);
+ test_qvm::scalar_multiply_v(x.b,x.a,2.0f);
+ test_same_type(x,2*x);
+ {
+ test_qvm::vector<V1,Dim> y=2*x;
+ BOOST_QVM_TEST_EQ(x.b,y.a);
+ }
+ {
+ test_qvm::vector<V1,Dim> y=2*vref(x);
+ BOOST_QVM_TEST_EQ(x.b,y.a);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test<1>();
+ test<2>();
+ test<3>();
+ test<4>();
+ test<5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/mul_vm_test.cpp b/src/boost/libs/qvm/test/mul_vm_test.cpp
new file mode 100644
index 000000000..17f703a69
--- /dev/null
+++ b/src/boost/libs/qvm/test/mul_vm_test.cpp
@@ -0,0 +1,75 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_operations.hpp>
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/vec_mat_operations.hpp>
+#include <boost/qvm/vec.hpp>
+#include "test_qvm_matrix.hpp"
+#include "test_qvm_vector.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <class T,class U>
+ struct same_type;
+
+ template <class T>
+ struct
+ same_type<T,T>
+ {
+ };
+
+ template <class T,class U>
+ void
+ check_same_type( T const &, U const & )
+ {
+ same_type<T,U>();
+ }
+
+ template <int M,int N>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ using namespace boost::qvm;
+ test_qvm::vector<V1,M> const x(42,1);
+ test_qvm::matrix<M1,M,N> const y(42,1);
+ {
+ test_qvm::vector<V2,N> r=x*y;
+ test_qvm::multiply_vm(r.b,x.b,y.b);
+ BOOST_QVM_TEST_CLOSE(r.a,r.b,0.0000001f);
+ }
+ {
+ test_qvm::vector<V2,N> r=vref(x)*y;
+ test_qvm::multiply_vm(r.b,x.b,y.b);
+ BOOST_QVM_TEST_CLOSE(r.a,r.b,0.0000001f);
+ }
+ {
+ test_qvm::vector<V2,N> r=x*mref(y);
+ test_qvm::multiply_vm(r.b,x.b,y.b);
+ BOOST_QVM_TEST_CLOSE(r.a,r.b,0.0000001f);
+ }
+ check_same_type(x*y,boost::qvm::vec<float,N>());
+ }
+ }
+
+int
+main()
+ {
+ test<1,2>();
+ test<2,1>();
+ test<2,2>();
+ test<1,3>();
+ test<3,1>();
+ test<3,3>();
+ test<1,4>();
+ test<4,1>();
+ test<4,4>();
+ test<1,5>();
+ test<5,1>();
+ test<5,5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/mul_vs_test.cpp b/src/boost/libs/qvm/test/mul_vs_test.cpp
new file mode 100644
index 000000000..833824549
--- /dev/null
+++ b/src/boost/libs/qvm/test/mul_vs_test.cpp
@@ -0,0 +1,45 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_operations.hpp>
+#include <boost/qvm/vec.hpp>
+#include "test_qvm_vector.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <class T,class U> struct same_type_tester;
+ template <class T> struct same_type_tester<T,T> { };
+ template <class T,class U> void test_same_type( T, U ) { same_type_tester<T,U>(); }
+
+ template <int Dim>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::vector<V1,Dim> const x(42,1);
+ test_qvm::scalar_multiply_v(x.b,x.a,2.0f);
+ test_same_type(x,x*2);
+ {
+ test_qvm::vector<V1,Dim> y=x*2;
+ BOOST_QVM_TEST_EQ(x.b,y.a);
+ }
+ {
+ test_qvm::vector<V1,Dim> y=vref(x)*2;
+ BOOST_QVM_TEST_EQ(x.b,y.a);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test<1>();
+ test<2>();
+ test<3>();
+ test<4>();
+ test<5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/neg_col_test.cpp b/src/boost/libs/qvm/test/neg_col_test.cpp
new file mode 100644
index 000000000..9ff94790b
--- /dev/null
+++ b/src/boost/libs/qvm/test/neg_col_test.cpp
@@ -0,0 +1,55 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/map_mat_mat.hpp>
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/mat_traits_array.hpp>
+#include <boost/qvm/mat.hpp>
+#include "test_qvm.hpp"
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Rows,int Cols,int Col>
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ test_qvm::matrix<M1,Rows,Cols> x(42,1);
+ float r1[Rows][Cols];
+ for( int i=0; i!=Rows; ++i )
+ for( int j=0; j!=Cols; ++j )
+ r1[i][j]=(j==Col?-x.a[i][j]:x.a[i][j]);
+ float r2[Rows][Cols];
+ assign(r2,neg_col<Col>(x));
+ BOOST_QVM_TEST_EQ(r1,r2);
+ neg_col<Col>(x) + neg_col<Col>(x);
+ -neg_col<Col>(x);
+ }
+ }
+
+int
+main()
+ {
+ test<2,2,0>();
+ test<2,2,1>();
+
+ test<3,3,0>();
+ test<3,3,1>();
+ test<3,3,2>();
+
+ test<4,4,0>();
+ test<4,4,1>();
+ test<4,4,2>();
+ test<4,4,3>();
+
+ test<5,5,0>();
+ test<5,5,1>();
+ test<5,5,2>();
+ test<5,5,3>();
+ test<5,5,4>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/neg_row_test.cpp b/src/boost/libs/qvm/test/neg_row_test.cpp
new file mode 100644
index 000000000..e8ad870de
--- /dev/null
+++ b/src/boost/libs/qvm/test/neg_row_test.cpp
@@ -0,0 +1,55 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/map_mat_mat.hpp>
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/mat_traits_array.hpp>
+#include <boost/qvm/mat.hpp>
+#include "test_qvm.hpp"
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Rows,int Cols,int Row>
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ test_qvm::matrix<M1,Rows,Cols> x(42,1);
+ float r1[Rows][Cols];
+ for( int i=0; i!=Rows; ++i )
+ for( int j=0; j!=Cols; ++j )
+ r1[i][j]=(i==Row?-x.a[i][j]:x.a[i][j]);
+ float r2[Rows][Cols];
+ assign(r2,neg_row<Row>(x));
+ BOOST_QVM_TEST_EQ(r1,r2);
+ neg_row<Row>(x) + neg_row<Row>(x);
+ -neg_row<Row>(x);
+ }
+ }
+
+int
+main()
+ {
+ test<2,2,0>();
+ test<2,2,1>();
+
+ test<3,3,0>();
+ test<3,3,1>();
+ test<3,3,2>();
+
+ test<4,4,0>();
+ test<4,4,1>();
+ test<4,4,2>();
+ test<4,4,3>();
+
+ test<5,5,0>();
+ test<5,5,1>();
+ test<5,5,2>();
+ test<5,5,3>();
+ test<5,5,4>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/normalize_q_test.cpp b/src/boost/libs/qvm/test/normalize_q_test.cpp
new file mode 100644
index 000000000..ad1b5f9ef
--- /dev/null
+++ b/src/boost/libs/qvm/test/normalize_q_test.cpp
@@ -0,0 +1,51 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/quat_operations.hpp>
+#include <boost/qvm/quat.hpp>
+#include "test_qvm_quaternion.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <class T,class U> struct same_type_tester;
+ template <class T> struct same_type_tester<T,T> { };
+ template <class T,class U> void test_same_type( T, U ) { same_type_tester<T,U>(); }
+
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ {
+ test_qvm::quaternion<Q1> const x(42,1);
+ test_same_type(x,normalized(x));
+ test_qvm::quaternion<Q1> y=normalized(x);
+ float m=sqrtf(test_qvm::dot<float>(x.a,x.a));
+ test_qvm::scalar_multiply_v(y.b,x.a,1/m);
+ BOOST_QVM_TEST_CLOSE(y.a,y.b,0.000001f);
+ }
+ {
+ test_qvm::quaternion<Q1> const x(42,1);
+ test_qvm::quaternion<Q1> y=normalized(qref(x));
+ float m=sqrtf(test_qvm::dot<float>(x.a,x.a));
+ test_qvm::scalar_multiply_v(y.b,x.a,1/m);
+ BOOST_QVM_TEST_CLOSE(y.a,y.b,0.000001f);
+ }
+ {
+ test_qvm::quaternion<Q1> x(42,1);
+ float m=sqrtf(test_qvm::dot<float>(x.a,x.a));
+ test_qvm::scalar_multiply_v(x.b,x.a,1/m);
+ normalize(x);
+ BOOST_QVM_TEST_CLOSE(x.a,x.b,0.000001f);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/normalize_v_test.cpp b/src/boost/libs/qvm/test/normalize_v_test.cpp
new file mode 100644
index 000000000..8bca04b0a
--- /dev/null
+++ b/src/boost/libs/qvm/test/normalize_v_test.cpp
@@ -0,0 +1,47 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_operations.hpp>
+#include "test_qvm_vector.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <class T,class U> struct same_type_tester;
+ template <class T> struct same_type_tester<T,T> { };
+ template <class T,class U> void test_same_type( T, U ) { same_type_tester<T,U>(); }
+
+ template <int Dim>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ {
+ test_qvm::vector<V1,Dim> const x(42,1);
+ test_same_type(x,normalized(x));
+ test_qvm::vector<V1,Dim> y=normalized(x);
+ float m=sqrtf(test_qvm::dot<float>(x.a,x.a));
+ test_qvm::scalar_multiply_v(y.b,x.a,1/m);
+ BOOST_QVM_TEST_CLOSE(y.a,y.b,0.000001f);
+ }
+ {
+ test_qvm::vector<V1,Dim> x(42,1);
+ float m=sqrtf(test_qvm::dot<float>(x.a,x.a));
+ test_qvm::scalar_multiply_v(x.b,x.a,1/m);
+ normalize(x);
+ BOOST_QVM_TEST_CLOSE(x.a,x.b,0.000001f);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test<2>();
+ test<3>();
+ test<4>();
+ test<5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/plus_eq_mm_test.cpp b/src/boost/libs/qvm/test/plus_eq_mm_test.cpp
new file mode 100644
index 000000000..fc4b5a260
--- /dev/null
+++ b/src/boost/libs/qvm/test/plus_eq_mm_test.cpp
@@ -0,0 +1,49 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/mat_operations.hpp>
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Rows,int Cols>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::matrix<M1,Rows,Cols> x(42,2);
+ {
+ test_qvm::matrix<M1,Rows,Cols> const y(42,1);
+ test_qvm::add_m(x.b,x.a,y.a);
+ x+=y;
+ BOOST_QVM_TEST_EQ(x.a,x.b);
+ }
+ {
+ test_qvm::matrix<M2,Rows,Cols> const y(42,1);
+ test_qvm::add_m(x.b,x.a,y.a);
+ x+=y;
+ BOOST_QVM_TEST_EQ(x.a,x.b);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test<1,2>();
+ test<2,1>();
+ test<2,2>();
+ test<1,3>();
+ test<3,1>();
+ test<3,3>();
+ test<1,4>();
+ test<4,1>();
+ test<4,4>();
+ test<1,5>();
+ test<5,1>();
+ test<5,5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/plus_eq_qq_test.cpp b/src/boost/libs/qvm/test/plus_eq_qq_test.cpp
new file mode 100644
index 000000000..22d911c2a
--- /dev/null
+++ b/src/boost/libs/qvm/test/plus_eq_qq_test.cpp
@@ -0,0 +1,37 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/quat_operations.hpp>
+#include "test_qvm_quaternion.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::quaternion<Q1> x(42,2);
+ {
+ test_qvm::quaternion<Q1> const y(42,1);
+ test_qvm::add_v(x.b,x.a,y.a);
+ x+=y;
+ BOOST_QVM_TEST_EQ(x.a,x.b);
+ }
+ {
+ test_qvm::quaternion<Q2> const y(42,1);
+ test_qvm::add_v(x.b,x.a,y.a);
+ x+=y;
+ BOOST_QVM_TEST_EQ(x.a,x.b);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/plus_eq_vv_test.cpp b/src/boost/libs/qvm/test/plus_eq_vv_test.cpp
new file mode 100644
index 000000000..c069edc45
--- /dev/null
+++ b/src/boost/libs/qvm/test/plus_eq_vv_test.cpp
@@ -0,0 +1,41 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_operations.hpp>
+#include "test_qvm_vector.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Dim>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::vector<V1,Dim> x(42,2);
+ {
+ test_qvm::vector<V1,Dim> const y(42,1);
+ test_qvm::add_v(x.b,x.a,y.a);
+ x+=y;
+ BOOST_QVM_TEST_EQ(x.a,x.b);
+ }
+ {
+ test_qvm::vector<V2,Dim> const y(42,1);
+ test_qvm::add_v(x.b,x.a,y.a);
+ x+=y;
+ BOOST_QVM_TEST_EQ(x.a,x.b);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test<2>();
+ test<3>();
+ test<4>();
+ test<5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/plus_mm_test.cpp b/src/boost/libs/qvm/test/plus_mm_test.cpp
new file mode 100644
index 000000000..f33aa053c
--- /dev/null
+++ b/src/boost/libs/qvm/test/plus_mm_test.cpp
@@ -0,0 +1,61 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/mat.hpp>
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <class T,class U> struct same_type_tester;
+ template <class T> struct same_type_tester<T,T> { };
+ template <class T,class U> void test_same_type( T, U ) { same_type_tester<T,U>(); }
+
+ template <int Rows,int Cols>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::matrix<M1,Rows,Cols> const x(42,2);
+ {
+ test_qvm::matrix<M1,Rows,Cols> const y(42,1);
+ test_same_type(x,x+y);
+ test_qvm::matrix<M1,Rows,Cols> r=x+y;
+ test_qvm::add_m(r.b,x.b,y.b);
+ BOOST_QVM_TEST_EQ(r.a,r.b);
+ }
+ {
+ test_qvm::matrix<M1,Rows,Cols> const y(42,1);
+ test_qvm::matrix<M2,Rows,Cols> r=mref(x)+y;
+ test_qvm::add_m(r.b,x.b,y.b);
+ BOOST_QVM_TEST_EQ(r.a,r.b);
+ }
+ {
+ test_qvm::matrix<M1,Rows,Cols> const y(42,1);
+ test_qvm::matrix<M2,Rows,Cols> r=x+mref(y);
+ test_qvm::add_m(r.b,x.b,y.b);
+ BOOST_QVM_TEST_EQ(r.a,r.b);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test<1,2>();
+ test<2,1>();
+ test<2,2>();
+ test<1,3>();
+ test<3,1>();
+ test<3,3>();
+ test<1,4>();
+ test<4,1>();
+ test<4,4>();
+ test<1,5>();
+ test<5,1>();
+ test<5,5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/plus_qq_test.cpp b/src/boost/libs/qvm/test/plus_qq_test.cpp
new file mode 100644
index 000000000..4b7546970
--- /dev/null
+++ b/src/boost/libs/qvm/test/plus_qq_test.cpp
@@ -0,0 +1,49 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/quat_operations.hpp>
+#include <boost/qvm/quat.hpp>
+#include "test_qvm_quaternion.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <class T,class U> struct same_type_tester;
+ template <class T> struct same_type_tester<T,T> { };
+ template <class T,class U> void test_same_type( T, U ) { same_type_tester<T,U>(); }
+
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::quaternion<Q1> const x(42,2);
+ {
+ test_qvm::quaternion<Q1> const y(42,1);
+ test_same_type(x,x+y);
+ test_qvm::quaternion<Q1> r=x+y;
+ test_qvm::add_v(r.b,x.b,y.b);
+ BOOST_QVM_TEST_EQ(r.a,r.b);
+ }
+ {
+ test_qvm::quaternion<Q1> const y(42,1);
+ test_qvm::quaternion<Q2> r=qref(x)+y;
+ test_qvm::add_v(r.b,x.b,y.b);
+ BOOST_QVM_TEST_EQ(r.a,r.b);
+ }
+ {
+ test_qvm::quaternion<Q1> const y(42,1);
+ test_qvm::quaternion<Q2> r=x+qref(y);
+ test_qvm::add_v(r.b,x.b,y.b);
+ BOOST_QVM_TEST_EQ(r.a,r.b);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/plus_vv_test.cpp b/src/boost/libs/qvm/test/plus_vv_test.cpp
new file mode 100644
index 000000000..f85c0e4a4
--- /dev/null
+++ b/src/boost/libs/qvm/test/plus_vv_test.cpp
@@ -0,0 +1,53 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_operations.hpp>
+#include <boost/qvm/vec.hpp>
+#include "test_qvm_vector.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <class T,class U> struct same_type_tester;
+ template <class T> struct same_type_tester<T,T> { };
+ template <class T,class U> void test_same_type( T, U ) { same_type_tester<T,U>(); }
+
+ template <int Dim>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::vector<V1,Dim> const x(42,2);
+ {
+ test_qvm::vector<V1,Dim> const y(42,1);
+ test_same_type(x,x+y);
+ test_qvm::vector<V1,Dim> r=x+y;
+ test_qvm::add_v(r.b,x.b,y.b);
+ BOOST_QVM_TEST_EQ(r.a,r.b);
+ }
+ {
+ test_qvm::vector<V1,Dim> const y(42,1);
+ test_qvm::vector<V2,Dim> r=vref(x)+y;
+ test_qvm::add_v(r.b,x.b,y.b);
+ BOOST_QVM_TEST_EQ(r.a,r.b);
+ }
+ {
+ test_qvm::vector<V1,Dim> const y(42,1);
+ test_qvm::vector<V2,Dim> r=x+vref(y);
+ test_qvm::add_v(r.b,x.b,y.b);
+ BOOST_QVM_TEST_EQ(r.a,r.b);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test<2>();
+ test<3>();
+ test<4>();
+ test<5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/projection_test.cpp b/src/boost/libs/qvm/test/projection_test.cpp
new file mode 100644
index 000000000..9959313c9
--- /dev/null
+++ b/src/boost/libs/qvm/test/projection_test.cpp
@@ -0,0 +1,39 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/mat_operations.hpp>
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <class T>
+ void
+ test_perspective_lh( T fov_y, T aspect_ratio, T z_near, T z_far )
+ {
+ using namespace boost::qvm;
+ test_qvm::matrix<M1,4,4> const m=perspective_lh(fov_y,aspect_ratio,z_near,z_far);
+ test_qvm::matrix_perspective_lh(m.b,fov_y,aspect_ratio,z_near,z_far);
+ BOOST_QVM_TEST_CLOSE(m.a,m.b,0.000001f);
+ }
+
+ template <class T>
+ void
+ test_perspective_rh( T fov_y, T aspect_ratio, T z_near, T z_far )
+ {
+ using namespace boost::qvm;
+ test_qvm::matrix<M1,4,4> const m=perspective_rh(fov_y,aspect_ratio,z_near,z_far);
+ test_qvm::matrix_perspective_rh(m.b,fov_y,aspect_ratio,z_near,z_far);
+ BOOST_QVM_TEST_CLOSE(m.a,m.b,0.000001f);
+ }
+ }
+
+int
+main()
+ {
+ test_perspective_lh(0.5f,1.3f,0.1f,2000.0f);
+ test_perspective_rh(0.5f,1.3f,0.1f,2000.0f);
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/quat_traits_array_test.cpp b/src/boost/libs/qvm/test/quat_traits_array_test.cpp
new file mode 100644
index 000000000..09fdf5b1f
--- /dev/null
+++ b/src/boost/libs/qvm/test/quat_traits_array_test.cpp
@@ -0,0 +1,92 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/quat_traits_array.hpp>
+#include <boost/qvm/quat_operations.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+template <class T,class U>
+struct same_type;
+
+template <class T>
+struct
+same_type<T,T>
+ {
+ };
+
+template <class T,class P>
+void
+test_ref_cast( T & q, P * ptr )
+ {
+ using namespace boost::qvm;
+ BOOST_QVM_STATIC_ASSERT(is_quat<T>::value);
+ BOOST_TEST(quat_traits<T>::template read_element<0>(q)==ptr[0]);
+ BOOST_TEST(quat_traits<T>::template read_element<1>(q)==ptr[1]);
+ BOOST_TEST(quat_traits<T>::template read_element<2>(q)==ptr[2]);
+ BOOST_TEST(quat_traits<T>::template read_element<3>(q)==ptr[3]);
+ BOOST_TEST(&quat_traits<T>::template write_element<0>(q)==&ptr[0]);
+ BOOST_TEST(&quat_traits<T>::template write_element<1>(q)==&ptr[1]);
+ BOOST_TEST(&quat_traits<T>::template write_element<2>(q)==&ptr[2]);
+ BOOST_TEST(&quat_traits<T>::template write_element<3>(q)==&ptr[3]);
+ BOOST_TEST(&q[0]==&ptr[0]);
+ BOOST_TEST(&q[1]==&ptr[1]);
+ BOOST_TEST(&q[2]==&ptr[2]);
+ BOOST_TEST(&q[3]==&ptr[3]);
+ }
+
+int
+main()
+ {
+ using namespace boost::qvm;
+ {
+ BOOST_QVM_STATIC_ASSERT(is_quat<int[4]>::value);
+ BOOST_QVM_STATIC_ASSERT(!is_quat<int[4][4]>::value);
+ BOOST_QVM_STATIC_ASSERT(!is_quat<int[4][4][4]>::value);
+ same_type<quat_traits<int[4]>::scalar_type,int>();
+ same_type< quat<int>, deduce_quat<int[4]>::type >();
+ same_type< quat<int>, deduce_quat<int const[4]>::type >();
+ int arr[4] = {0,1,2,3};
+ BOOST_TEST((quat_traits<int[4]>::read_element<0>(arr)==0));
+ BOOST_TEST((quat_traits<int[4]>::read_element<1>(arr)==1));
+ BOOST_TEST((quat_traits<int[4]>::read_element<2>(arr)==2));
+ BOOST_TEST((quat_traits<int[4]>::read_element<3>(arr)==3));
+ BOOST_TEST((quat_traits<int const[4]>::read_element<0>(arr)==0));
+ BOOST_TEST((quat_traits<int const[4]>::read_element<1>(arr)==1));
+ BOOST_TEST((quat_traits<int const[4]>::read_element<2>(arr)==2));
+ BOOST_TEST((quat_traits<int const[4]>::read_element<3>(arr)==3));
+ BOOST_TEST((quat_traits<int[4]>::read_element_idx(0,arr)==0));
+ BOOST_TEST((quat_traits<int[4]>::read_element_idx(1,arr)==1));
+ BOOST_TEST((quat_traits<int[4]>::read_element_idx(2,arr)==2));
+ BOOST_TEST((quat_traits<int[4]>::read_element_idx(3,arr)==3));
+ BOOST_TEST((quat_traits<int const[4]>::read_element_idx(0,arr)==0));
+ BOOST_TEST((quat_traits<int const[4]>::read_element_idx(1,arr)==1));
+ BOOST_TEST((quat_traits<int const[4]>::read_element_idx(2,arr)==2));
+ BOOST_TEST((quat_traits<int const[4]>::read_element_idx(3,arr)==3));
+ BOOST_TEST((&quat_traits<int[4]>::write_element<0>(arr)==&arr[0]));
+ BOOST_TEST((&quat_traits<int[4]>::write_element<1>(arr)==&arr[1]));
+ BOOST_TEST((&quat_traits<int[4]>::write_element<2>(arr)==&arr[2]));
+ BOOST_TEST((&quat_traits<int[4]>::write_element<3>(arr)==&arr[3]));
+ BOOST_TEST((&quat_traits<int[4]>::write_element_idx(0,arr)==&arr[0]));
+ BOOST_TEST((&quat_traits<int[4]>::write_element_idx(1,arr)==&arr[1]));
+ BOOST_TEST((&quat_traits<int[4]>::write_element_idx(2,arr)==&arr[2]));
+ BOOST_TEST((&quat_traits<int[4]>::write_element_idx(3,arr)==&arr[3]));
+ }
+ {
+ int arr[42] = {0};
+ int * ptr=arr+5;
+ ptr[0]=42;
+ ptr[1]=43;
+ ptr[2]=44;
+ ptr[3]=45;
+ test_ref_cast(ptr_qref(ptr),ptr);
+ int q[4] = {1,1,1,1};
+ ptr_qref(ptr) += qref(q);
+ BOOST_TEST(ptr[0]==43);
+ BOOST_TEST(ptr[1]==44);
+ BOOST_TEST(ptr[2]==45);
+ BOOST_TEST(ptr[3]==46);
+ }
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/rot_mat_test.cpp b/src/boost/libs/qvm/test/rot_mat_test.cpp
new file mode 100644
index 000000000..a4638c0c8
--- /dev/null
+++ b/src/boost/libs/qvm/test/rot_mat_test.cpp
@@ -0,0 +1,433 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/mat.hpp>
+#include "test_qvm_matrix.hpp"
+#include "test_qvm_vector.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int D>
+ void
+ test_x()
+ {
+ using namespace boost::qvm;
+ test_qvm::vector<V1,3> axis; axis.a[0]=1;
+ for( float r=0; r<6.28f; r+=0.5f )
+ {
+ test_qvm::matrix<M1,D,D> const m1=rot_mat<D>(axis,r);
+ test_qvm::rotation_x(m1.b,r);
+ BOOST_QVM_TEST_EQ(m1.a,m1.b);
+ test_qvm::matrix<M1,D,D> m2(42,1);
+ set_rot(m2,axis,r);
+ test_qvm::rotation_x(m2.b,r);
+ BOOST_QVM_TEST_EQ(m2.a,m2.b);
+ test_qvm::matrix<M1,D,D> m3(42,1);
+ test_qvm::matrix<M1,D,D> m4(42,1);
+ rotate(m3,axis,r);
+ m3 = m3*m1;
+ BOOST_QVM_TEST_EQ(m3.a,m3.a);
+ }
+ }
+
+ template <int D>
+ void
+ test_y()
+ {
+ using namespace boost::qvm;
+ test_qvm::vector<V1,3> axis; axis.a[1]=1;
+ for( float r=0; r<6.28f; r+=0.5f )
+ {
+ test_qvm::matrix<M1,D,D> m1=rot_mat<D>(axis,r);
+ test_qvm::rotation_y(m1.b,r);
+ BOOST_QVM_TEST_EQ(m1.a,m1.b);
+ test_qvm::matrix<M1,D,D> m2(42,1);
+ set_rot(m2,axis,r);
+ test_qvm::rotation_y(m2.b,r);
+ BOOST_QVM_TEST_EQ(m2.a,m2.b);
+ test_qvm::matrix<M1,D,D> m3(42,1);
+ test_qvm::matrix<M1,D,D> m4(42,1);
+ rotate(m3,axis,r);
+ m3 = m3*m1;
+ BOOST_QVM_TEST_EQ(m3.a,m3.a);
+ }
+ }
+
+ template <int D>
+ void
+ test_z()
+ {
+ using namespace boost::qvm;
+ test_qvm::vector<V1,3> axis; axis.a[2]=1;
+ for( float r=0; r<6.28f; r+=0.5f )
+ {
+ test_qvm::matrix<M1,D,D> m1=rot_mat<D>(axis,r);
+ test_qvm::rotation_z(m1.b,r);
+ BOOST_QVM_TEST_EQ(m1.a,m1.b);
+ test_qvm::matrix<M1,D,D> m2(42,1);
+ set_rot(m2,axis,r);
+ test_qvm::rotation_z(m2.b,r);
+ BOOST_QVM_TEST_EQ(m2.a,m2.b);
+ test_qvm::matrix<M1,D,D> m3(42,1);
+ test_qvm::matrix<M1,D,D> m4(42,1);
+ rotate(m3,axis,r);
+ m3 = m3*m1;
+ BOOST_QVM_TEST_EQ(m3.a,m3.a);
+ }
+ }
+
+ template <int D>
+ void
+ test_xzy()
+ {
+ using namespace boost::qvm;
+ for( float x1=0; x1<6.28f; x1+=0.5f )
+ for( float z2=0; z2<6.28f; z2+=0.5f )
+ for( float y3=0; y3<6.28f; y3+=0.5f )
+ {
+ mat<float,D,D> const m2 = rotx_mat<D>(x1) * rotz_mat<D>(z2) * roty_mat<D>(y3);
+ {
+ mat<float,D,D> m1 = rot_mat_xzy<D>(x1,z2,y3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ {
+ mat<float,D,D> m1; set_rot_xzy(m1,x1,z2,y3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ {
+ mat<float,D,D> m1 = identity_mat<float,D>(); rotate_xzy(m1,x1,z2,y3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ }
+ }
+
+ template <int D>
+ void
+ test_xyz()
+ {
+ using namespace boost::qvm;
+ for( float x1=0; x1<6.28f; x1+=0.5f )
+ for( float y2=0; y2<6.28f; y2+=0.5f )
+ for( float z3=0; z3<6.28f; z3+=0.5f )
+ {
+ mat<float,D,D> const m2 = rotx_mat<D>(x1) * roty_mat<D>(y2) * rotz_mat<D>(z3);
+ {
+ mat<float,D,D> m1 = rot_mat_xyz<D>(x1,y2,z3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ {
+ mat<float,D,D> m1; set_rot_xyz(m1,x1,y2,z3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ {
+ mat<float,D,D> m1 = identity_mat<float,D>(); rotate_xyz(m1,x1,y2,z3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ }
+ }
+
+ template <int D>
+ void
+ test_yxz()
+ {
+ using namespace boost::qvm;
+ for( float y1=0; y1<6.28f; y1+=0.5f )
+ for( float x2=0; x2<6.28f; x2+=0.5f )
+ for( float z3=0; z3<6.28f; z3+=0.5f )
+ {
+ mat<float,D,D> const m2 = roty_mat<D>(y1) * rotx_mat<D>(x2) * rotz_mat<D>(z3);
+ {
+ mat<float,D,D> m1 = rot_mat_yxz<D>(y1,x2,z3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ {
+ mat<float,D,D> m1; set_rot_yxz(m1,y1,x2,z3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ {
+ mat<float,D,D> m1 = identity_mat<float,D>(); rotate_yxz(m1,y1,x2,z3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ }
+ }
+
+ template <int D>
+ void
+ test_yzx()
+ {
+ using namespace boost::qvm;
+ for( float y1=0; y1<6.28f; y1+=0.5f )
+ for( float z2=0; z2<6.28f; z2+=0.5f )
+ for( float x3=0; x3<6.28f; x3+=0.5f )
+ {
+ mat<float,D,D> const m2 = roty_mat<D>(y1) * rotz_mat<D>(z2) * rotx_mat<D>(x3);
+ {
+ mat<float,D,D> m1 = rot_mat_yzx<D>(y1,z2,x3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ {
+ mat<float,D,D> m1; set_rot_yzx(m1,y1,z2,x3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ {
+ mat<float,D,D> m1 = identity_mat<float,D>(); rotate_yzx(m1,y1,z2,x3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ }
+ }
+
+ template <int D>
+ void
+ test_zyx()
+ {
+ using namespace boost::qvm;
+ for( float z1=0; z1<6.28f; z1+=0.5f )
+ for( float y2=0; y2<6.28f; y2+=0.5f )
+ for( float x3=0; x3<6.28f; x3+=0.5f )
+ {
+ mat<float,D,D> const m2 = rotz_mat<D>(z1) * roty_mat<D>(y2) * rotx_mat<D>(x3);
+ {
+ mat<float,D,D> m1 = rot_mat_zyx<D>(z1,y2,x3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ {
+ mat<float,D,D> m1; set_rot_zyx(m1,z1,y2,x3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ {
+ mat<float,D,D> m1 = identity_mat<float,D>(); rotate_zyx(m1,z1,y2,x3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ }
+ }
+
+ template <int D>
+ void
+ test_zxy()
+ {
+ using namespace boost::qvm;
+ for( float z1=0; z1<6.28f; z1+=0.5f )
+ for( float x2=0; x2<6.28f; x2+=0.5f )
+ for( float y3=0; y3<6.28f; y3+=0.5f )
+ {
+ mat<float,D,D> const m2 = rotz_mat<D>(z1) * rotx_mat<D>(x2) * roty_mat<D>(y3);
+ {
+ mat<float,D,D> m1 = rot_mat_zxy<D>(z1,x2,y3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ {
+ mat<float,D,D> m1; set_rot_zxy(m1,z1,x2,y3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ {
+ mat<float,D,D> m1 = identity_mat<float,D>(); rotate_zxy(m1,z1,x2,y3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ }
+ }
+
+ template <int D>
+ void
+ test_xzx()
+ {
+ using namespace boost::qvm;
+ for( float x1=0; x1<6.28f; x1+=0.5f )
+ for( float z2=0; z2<6.28f; z2+=0.5f )
+ for( float x3=0; x3<6.28f; x3+=0.5f )
+ {
+ mat<float,D,D> const m2 = rotx_mat<D>(x1) * rotz_mat<D>(z2) * rotx_mat<D>(x3);
+ {
+ mat<float,D,D> m1 = rot_mat_xzx<D>(x1,z2,x3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ {
+ mat<float,D,D> m1; set_rot_xzx(m1,x1,z2,x3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ {
+ mat<float,D,D> m1 = identity_mat<float,D>(); rotate_xzx(m1,x1,z2,x3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ }
+ }
+
+ template <int D>
+ void
+ test_xyx()
+ {
+ using namespace boost::qvm;
+ for( float x1=0; x1<6.28f; x1+=0.5f )
+ for( float y2=0; y2<6.28f; y2+=0.5f )
+ for( float x3=0; x3<6.28f; x3+=0.5f )
+ {
+ mat<float,D,D> const m2 = rotx_mat<D>(x1) * roty_mat<D>(y2) * rotx_mat<D>(x3);
+ {
+ mat<float,D,D> m1 = rot_mat_xyx<D>(x1,y2,x3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ {
+ mat<float,D,D> m1; set_rot_xyx(m1,x1,y2,x3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ {
+ mat<float,D,D> m1 = identity_mat<float,D>(); rotate_xyx(m1,x1,y2,x3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ }
+ }
+
+ template <int D>
+ void
+ test_yxy()
+ {
+ using namespace boost::qvm;
+ for( float y1=0; y1<6.28f; y1+=0.5f )
+ for( float x2=0; x2<6.28f; x2+=0.5f )
+ for( float y3=0; y3<6.28f; y3+=0.5f )
+ {
+ mat<float,D,D> const m2 = roty_mat<D>(y1) * rotx_mat<D>(x2) * roty_mat<D>(y3);
+ {
+ mat<float,D,D> m1 = rot_mat_yxy<D>(y1,x2,y3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ {
+ mat<float,D,D> m1; set_rot_yxy(m1,y1,x2,y3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ {
+ mat<float,D,D> m1 = identity_mat<float,D>(); rotate_yxy(m1,y1,x2,y3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ }
+ }
+
+ template <int D>
+ void
+ test_yzy()
+ {
+ using namespace boost::qvm;
+ for( float y1=0; y1<6.28f; y1+=0.5f )
+ for( float z2=0; z2<6.28f; z2+=0.5f )
+ for( float y3=0; y3<6.28f; y3+=0.5f )
+ {
+ mat<float,D,D> const m2 = roty_mat<D>(y1) * rotz_mat<D>(z2) * roty_mat<D>(y3);
+ {
+ mat<float,D,D> m1 = rot_mat_yzy<D>(y1,z2,y3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ {
+ mat<float,D,D> m1; set_rot_yzy(m1,y1,z2,y3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ {
+ mat<float,D,D> m1 = identity_mat<float,D>(); rotate_yzy(m1,y1,z2,y3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ }
+ }
+
+ template <int D>
+ void
+ test_zyz()
+ {
+ using namespace boost::qvm;
+ for( float z1=0; z1<6.28f; z1+=0.5f )
+ for( float y2=0; y2<6.28f; y2+=0.5f )
+ for( float z3=0; z3<6.28f; z3+=0.5f )
+ {
+ mat<float,D,D> const m2 = rotz_mat<D>(z1) * roty_mat<D>(y2) * rotz_mat<D>(z3);
+ {
+ mat<float,D,D> m1 = rot_mat_zyz<D>(z1,y2,z3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ {
+ mat<float,D,D> m1; set_rot_zyz(m1,z1,y2,z3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ {
+ mat<float,D,D> m1 = identity_mat<float,D>(); rotate_zyz(m1,z1,y2,z3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ }
+ }
+
+ template <int D>
+ void
+ test_zxz()
+ {
+ using namespace boost::qvm;
+ for( float z1=0; z1<6.28f; z1+=0.5f )
+ for( float x2=0; x2<6.28f; x2+=0.5f )
+ for( float z3=0; z3<6.28f; z3+=0.5f )
+ {
+ mat<float,D,D> const m2 = rotz_mat<D>(z1) * rotx_mat<D>(x2) * rotz_mat<D>(z3);
+ {
+ mat<float,D,D> m1 = rot_mat_zxz<D>(z1,x2,z3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ {
+ mat<float,D,D> m1; set_rot_zxz(m1,z1,x2,z3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ {
+ mat<float,D,D> m1 = identity_mat<float,D>(); rotate_zxz(m1,z1,x2,z3);
+ BOOST_QVM_TEST_CLOSE(m1.a,m2.a,0.0002f);
+ }
+ }
+ }
+ }
+
+int
+main()
+ {
+ test_x<3>();
+ test_y<3>();
+ test_z<3>();
+ test_xzy<3>();
+ test_xyz<3>();
+ test_yxz<3>();
+ test_yzx<3>();
+ test_zyx<3>();
+ test_zxy<3>();
+ test_xzx<3>();
+ test_xyx<3>();
+ test_yxy<3>();
+ test_yzy<3>();
+ test_zyz<3>();
+ test_zxz<3>();
+ test_x<4>();
+ test_y<4>();
+ test_z<4>();
+ test_xzy<4>();
+ test_xyz<4>();
+ test_yxz<4>();
+ test_yzx<4>();
+ test_zyx<4>();
+ test_zxy<4>();
+ test_xzx<4>();
+ test_xyx<4>();
+ test_yxy<4>();
+ test_yzy<4>();
+ test_zyz<4>();
+ test_zxz<4>();
+ test_x<5>();
+ test_y<5>();
+ test_z<5>();
+ test_xzy<5>();
+ test_xyz<5>();
+ test_yxz<5>();
+ test_yzx<5>();
+ test_zyx<5>();
+ test_zxy<5>();
+ test_xzx<5>();
+ test_xyx<5>();
+ test_yxy<5>();
+ test_yzy<5>();
+ test_zyz<5>();
+ test_zxz<5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/rot_quat_test.cpp b/src/boost/libs/qvm/test/rot_quat_test.cpp
new file mode 100644
index 000000000..1a31d1d65
--- /dev/null
+++ b/src/boost/libs/qvm/test/rot_quat_test.cpp
@@ -0,0 +1,95 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/quat_operations.hpp>
+#include <boost/qvm/mat_operations.hpp>
+#include "test_qvm_matrix.hpp"
+#include "test_qvm_quaternion.hpp"
+#include "test_qvm_vector.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ void
+ test_x()
+ {
+ using namespace boost::qvm;
+ test_qvm::vector<V1,3> axis; axis.a[0]=1;
+ for( float r=0; r<6.28f; r+=0.5f )
+ {
+ test_qvm::quaternion<Q1> q1=rot_quat(axis,r);
+ test_qvm::matrix<M1,3,3> x1=convert_to< test_qvm::matrix<M1,3,3> >(q1);
+ test_qvm::rotation_x(x1.b,r);
+ BOOST_QVM_TEST_CLOSE(x1.a,x1.b,0.000001f);
+ test_qvm::quaternion<Q2> q2(42,1);
+ set_rot(q2,axis,r);
+ test_qvm::matrix<M2,3,3> x2=convert_to< test_qvm::matrix<M2,3,3> >(q2);
+ test_qvm::rotation_x(x2.b,r);
+ BOOST_QVM_TEST_CLOSE(x2.a,x2.b,0.000001f);
+ test_qvm::quaternion<Q1> q3(42,1);
+ test_qvm::quaternion<Q1> q4(42,1);
+ rotate(q3,axis,r);
+ q3 = q3*q1;
+ BOOST_QVM_TEST_EQ(q3.a,q3.a);
+ }
+ }
+
+ void
+ test_y()
+ {
+ using namespace boost::qvm;
+ test_qvm::vector<V1,3> axis; axis.a[1]=1;
+ for( float r=0; r<6.28f; r+=0.5f )
+ {
+ test_qvm::quaternion<Q1> q1=rot_quat(axis,r);
+ test_qvm::matrix<M1,3,3> x1=convert_to< test_qvm::matrix<M1,3,3> >(q1);
+ test_qvm::rotation_y(x1.b,r);
+ BOOST_QVM_TEST_CLOSE(x1.a,x1.b,0.000001f);
+ test_qvm::quaternion<Q2> q2(42,1);
+ set_rot(q2,axis,r);
+ test_qvm::matrix<M2,3,3> x2=convert_to< test_qvm::matrix<M2,3,3> >(q2);
+ test_qvm::rotation_y(x2.b,r);
+ BOOST_QVM_TEST_CLOSE(x2.a,x2.b,0.000001f);
+ test_qvm::quaternion<Q1> q3(42,1);
+ test_qvm::quaternion<Q1> q4(42,1);
+ rotate(q3,axis,r);
+ q3 = q3*q1;
+ BOOST_QVM_TEST_EQ(q3.a,q3.a);
+ }
+ }
+
+ void
+ test_z()
+ {
+ using namespace boost::qvm;
+ test_qvm::vector<V1,3> axis; axis.a[2]=1;
+ for( float r=0; r<6.28f; r+=0.5f )
+ {
+ test_qvm::quaternion<Q1> q1=rot_quat(axis,r);
+ test_qvm::matrix<M1,3,3> x1=convert_to< test_qvm::matrix<M1,3,3> >(q1);
+ test_qvm::rotation_z(x1.b,r);
+ BOOST_QVM_TEST_CLOSE(x1.a,x1.b,0.000001f);
+ test_qvm::quaternion<Q2> q2(42,1);
+ set_rot(q2,axis,r);
+ test_qvm::matrix<M2,3,3> x2=convert_to< test_qvm::matrix<M2,3,3> >(q2);
+ test_qvm::rotation_z(x2.b,r);
+ BOOST_QVM_TEST_CLOSE(x2.a,x2.b,0.000001f);
+ test_qvm::quaternion<Q1> q3(42,1);
+ test_qvm::quaternion<Q1> q4(42,1);
+ rotate(q3,axis,r);
+ q3 = q3*q1;
+ BOOST_QVM_TEST_EQ(q3.a,q3.a);
+ }
+ }
+ }
+
+int
+main()
+ {
+ test_x();
+ test_y();
+ test_z();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/rotx_mat_test.cpp b/src/boost/libs/qvm/test/rotx_mat_test.cpp
new file mode 100644
index 000000000..bd3e6694a
--- /dev/null
+++ b/src/boost/libs/qvm/test/rotx_mat_test.cpp
@@ -0,0 +1,44 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/mat.hpp>
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Dim>
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ for( float r=0; r<6.28f; r+=0.5f )
+ {
+ test_qvm::matrix<M1,Dim,Dim> const m1=rotx_mat<Dim>(r);
+ test_qvm::rotation_x(m1.b,r);
+ BOOST_QVM_TEST_CLOSE(m1.a,m1.b,0.000001f);
+ test_qvm::matrix<M1,Dim,Dim> m2(42,1);
+ set_rotx(m2,r);
+ test_qvm::rotation_x(m2.b,r);
+ BOOST_QVM_TEST_CLOSE(m2.a,m2.b,0.000001f);
+ test_qvm::matrix<M1,Dim,Dim> m3(42,1);
+ test_qvm::matrix<M1,Dim,Dim> r1=m3*m1;
+ rotate_x(m3,r);
+ BOOST_QVM_TEST_EQ(m3.a,r1.a);
+ }
+ rotx_mat<Dim>(0.0f)+rotx_mat<Dim>(0.0f);
+ -rotx_mat<Dim>(0.0f);
+ }
+ }
+
+int
+main()
+ {
+ test<3>();
+ test<4>();
+ test<5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/rotx_quat_test.cpp b/src/boost/libs/qvm/test/rotx_quat_test.cpp
new file mode 100644
index 000000000..d2c598181
--- /dev/null
+++ b/src/boost/libs/qvm/test/rotx_quat_test.cpp
@@ -0,0 +1,45 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/quat_operations.hpp>
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/quat.hpp>
+#include "test_qvm_quaternion.hpp"
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ for( float r=0; r<6.28f; r+=0.5f )
+ {
+ test_qvm::quaternion<Q1> q1=rotx_quat(r);
+ test_qvm::matrix<M1,3,3> m1=convert_to< test_qvm::matrix<M1,3,3> >(q1);
+ test_qvm::rotation_x(m1.b,r);
+ BOOST_QVM_TEST_CLOSE(m1.a,m1.b,0.000001f);
+ test_qvm::quaternion<Q2> q2(42,1);
+ set_rotx(q2,r);
+ test_qvm::matrix<M1,3,3> m2=convert_to< test_qvm::matrix<M1,3,3> >(q2);
+ test_qvm::rotation_x(m2.b,r);
+ BOOST_QVM_TEST_CLOSE(m2.a,m2.b,0.000001f);
+ test_qvm::quaternion<Q1> q3(42,1);
+ test_qvm::quaternion<Q1> r1=q3*q1;
+ rotate_x(q3,r);
+ BOOST_QVM_TEST_EQ(q3.a,r1.a);
+ }
+ rotx_quat(0.0f)+rotx_quat(0.0f);
+ -rotx_quat(0.0f);
+ }
+ }
+
+int
+main()
+ {
+ test();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/roty_mat_test.cpp b/src/boost/libs/qvm/test/roty_mat_test.cpp
new file mode 100644
index 000000000..98cdf7ae5
--- /dev/null
+++ b/src/boost/libs/qvm/test/roty_mat_test.cpp
@@ -0,0 +1,44 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/mat.hpp>
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Dim>
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ for( float r=0; r<6.28f; r+=0.5f )
+ {
+ test_qvm::matrix<M1,Dim,Dim> const m1=roty_mat<Dim>(r);
+ test_qvm::rotation_y(m1.b,r);
+ BOOST_QVM_TEST_CLOSE(m1.a,m1.b,0.000001f);
+ test_qvm::matrix<M1,Dim,Dim> m2(42,1);
+ set_roty(m2,r);
+ test_qvm::rotation_y(m2.b,r);
+ BOOST_QVM_TEST_CLOSE(m2.a,m2.b,0.000001f);
+ test_qvm::matrix<M1,Dim,Dim> m3(42,1);
+ test_qvm::matrix<M1,Dim,Dim> r1=m3*m1;
+ rotate_y(m3,r);
+ BOOST_QVM_TEST_EQ(m3.a,r1.a);
+ }
+ roty_mat<Dim>(0.0f)+roty_mat<Dim>(0.0f);
+ -roty_mat<Dim>(0.0f);
+ }
+ }
+
+int
+main()
+ {
+ test<3>();
+ test<4>();
+ test<5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/roty_quat_test.cpp b/src/boost/libs/qvm/test/roty_quat_test.cpp
new file mode 100644
index 000000000..0f88efe0c
--- /dev/null
+++ b/src/boost/libs/qvm/test/roty_quat_test.cpp
@@ -0,0 +1,45 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/quat_operations.hpp>
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/quat.hpp>
+#include "test_qvm_quaternion.hpp"
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ for( float r=0; r<6.28f; r+=0.5f )
+ {
+ test_qvm::quaternion<Q1> q1=roty_quat(r);
+ test_qvm::matrix<M1,3,3> m1=convert_to< test_qvm::matrix<M1,3,3> >(q1);
+ test_qvm::rotation_y(m1.b,r);
+ BOOST_QVM_TEST_CLOSE(m1.a,m1.b,0.000001f);
+ test_qvm::quaternion<Q2> q2(42,1);
+ set_roty(q2,r);
+ test_qvm::matrix<M1,3,3> m2=convert_to< test_qvm::matrix<M1,3,3> >(q2);
+ test_qvm::rotation_y(m2.b,r);
+ BOOST_QVM_TEST_CLOSE(m2.a,m2.b,0.000001f);
+ test_qvm::quaternion<Q1> q3(42,1);
+ test_qvm::quaternion<Q1> r1=q3*q1;
+ rotate_y(q3,r);
+ BOOST_QVM_TEST_EQ(q3.a,r1.a);
+ }
+ roty_quat(0.0f)+roty_quat(0.0f);
+ -roty_quat(0.0f);
+ }
+ }
+
+int
+main()
+ {
+ test();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/rotz_mat_test.cpp b/src/boost/libs/qvm/test/rotz_mat_test.cpp
new file mode 100644
index 000000000..a186c2e58
--- /dev/null
+++ b/src/boost/libs/qvm/test/rotz_mat_test.cpp
@@ -0,0 +1,45 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/mat.hpp>
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Dim>
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ for( float r=0; r<6.28f; r+=0.5f )
+ {
+ test_qvm::matrix<M1,Dim,Dim> const m1=rotz_mat<Dim>(r);
+ test_qvm::rotation_z(m1.b,r);
+ BOOST_QVM_TEST_CLOSE(m1.a,m1.b,0.000001f);
+ test_qvm::matrix<M1,Dim,Dim> m2(42,1);
+ set_rotz(m2,r);
+ test_qvm::rotation_z(m2.b,r);
+ BOOST_QVM_TEST_CLOSE(m2.a,m2.b,0.000001f);
+ test_qvm::matrix<M1,Dim,Dim> m3(42,1);
+ test_qvm::matrix<M1,Dim,Dim> r1=m3*m1;
+ rotate_z(m3,r);
+ BOOST_QVM_TEST_EQ(m3.a,r1.a);
+ }
+ rotz_mat<Dim>(0.0f)+rotz_mat<Dim>(0.0f);
+ -rotz_mat<Dim>(0.0f);
+ }
+ }
+
+int
+main()
+ {
+ test<2>();
+ test<3>();
+ test<4>();
+ test<5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/rotz_quat_test.cpp b/src/boost/libs/qvm/test/rotz_quat_test.cpp
new file mode 100644
index 000000000..e6a3577c8
--- /dev/null
+++ b/src/boost/libs/qvm/test/rotz_quat_test.cpp
@@ -0,0 +1,45 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/quat_operations.hpp>
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/quat.hpp>
+#include "test_qvm_quaternion.hpp"
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ for( float r=0; r<6.28f; r+=0.5f )
+ {
+ test_qvm::quaternion<Q1> q1=rotz_quat(r);
+ test_qvm::matrix<M1,3,3> m1=convert_to< test_qvm::matrix<M1,3,3> >(q1);
+ test_qvm::rotation_z(m1.b,r);
+ BOOST_QVM_TEST_CLOSE(m1.a,m1.b,0.000001f);
+ test_qvm::quaternion<Q2> q2(42,1);
+ set_rotz(q2,r);
+ test_qvm::matrix<M1,3,3> m2=convert_to< test_qvm::matrix<M1,3,3> >(q2);
+ test_qvm::rotation_z(m2.b,r);
+ BOOST_QVM_TEST_CLOSE(m2.a,m2.b,0.000001f);
+ test_qvm::quaternion<Q1> q3(42,1);
+ test_qvm::quaternion<Q1> r1=q3*q1;
+ rotate_z(q3,r);
+ BOOST_QVM_TEST_EQ(q3.a,r1.a);
+ }
+ rotz_quat(0.0f)+rotz_quat(0.0f);
+ -rotz_quat(0.0f);
+ }
+ }
+
+int
+main()
+ {
+ test();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/row_mat_test.cpp b/src/boost/libs/qvm/test/row_mat_test.cpp
new file mode 100644
index 000000000..9aa3ec54d
--- /dev/null
+++ b/src/boost/libs/qvm/test/row_mat_test.cpp
@@ -0,0 +1,40 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/map.hpp>
+#include <boost/qvm/mat_traits_array.hpp>
+#include <boost/qvm/vec_operations.hpp>
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/mat.hpp>
+#include "test_qvm_vector.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Dim>
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ test_qvm::vector<V1,Dim> x(42,1);
+ float y[1][Dim]; assign(y,row_mat(x));
+ BOOST_QVM_TEST_EQ(x.a,y[0]);
+ test_qvm::scalar_multiply_v(x.b,x.a,2.0f);
+ row<0>(row_mat(x)) *= 2;
+ BOOST_QVM_TEST_EQ(x.a,x.b);
+ row_mat(x) + row_mat(x);
+ -row_mat(x);
+ }
+ }
+
+int
+main()
+ {
+ test<2>();
+ test<3>();
+ test<4>();
+ test<5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/row_test.cpp b/src/boost/libs/qvm/test/row_test.cpp
new file mode 100644
index 000000000..972e0762c
--- /dev/null
+++ b/src/boost/libs/qvm/test/row_test.cpp
@@ -0,0 +1,118 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/map_mat_vec.hpp>
+#include <boost/qvm/vec_traits_array.hpp>
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/vec_operations.hpp>
+#include <boost/qvm/vec.hpp>
+#include "test_qvm.hpp"
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Rows,int Cols,int Row>
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ test_qvm::matrix<M1,Rows,Cols> x(42,1);
+ float r1[Cols];
+ for( int i=0; i!=Cols; ++i )
+ r1[i]=x.a[Row][i];
+ float r2[Cols];
+ assign(r2,row<Row>(x));
+ BOOST_QVM_TEST_EQ(r1,r2);
+ row<Row>(x) *= 2;
+ for( int i=0; i!=Cols; ++i )
+ r1[i]=x.a[Row][i];
+ assign(r2,row<Row>(x));
+ BOOST_QVM_TEST_EQ(r1,r2);
+ row<Row>(x) + row<Row>(x);
+ -row<Row>(x);
+ }
+ }
+
+int
+main()
+ {
+ test<2,1,0>();
+ test<2,1,1>();
+ test<3,1,0>();
+ test<3,1,1>();
+ test<3,1,2>();
+ test<4,1,0>();
+ test<4,1,1>();
+ test<4,1,2>();
+ test<4,1,3>();
+ test<5,1,0>();
+ test<5,1,1>();
+ test<5,1,2>();
+ test<5,1,3>();
+ test<5,1,4>();
+
+ test<2,2,0>();
+ test<2,2,1>();
+ test<3,2,0>();
+ test<3,2,1>();
+ test<3,2,2>();
+ test<4,2,0>();
+ test<4,2,1>();
+ test<4,2,2>();
+ test<4,2,3>();
+ test<5,2,0>();
+ test<5,2,1>();
+ test<5,2,2>();
+ test<5,2,3>();
+ test<5,2,4>();
+
+ test<2,3,0>();
+ test<2,3,1>();
+ test<3,3,0>();
+ test<3,3,1>();
+ test<3,3,2>();
+ test<4,3,0>();
+ test<4,3,1>();
+ test<4,3,2>();
+ test<4,3,3>();
+ test<5,3,0>();
+ test<5,3,1>();
+ test<5,3,2>();
+ test<5,3,3>();
+ test<5,3,4>();
+
+ test<2,4,0>();
+ test<2,4,1>();
+ test<3,4,0>();
+ test<3,4,1>();
+ test<3,4,2>();
+ test<4,4,0>();
+ test<4,4,1>();
+ test<4,4,2>();
+ test<4,4,3>();
+ test<5,4,0>();
+ test<5,4,1>();
+ test<5,4,2>();
+ test<5,4,3>();
+ test<5,4,4>();
+
+ test<2,5,0>();
+ test<2,5,1>();
+ test<3,5,0>();
+ test<3,5,1>();
+ test<3,5,2>();
+ test<4,5,0>();
+ test<4,5,1>();
+ test<4,5,2>();
+ test<4,5,3>();
+ test<5,5,0>();
+ test<5,5,1>();
+ test<5,5,2>();
+ test<5,5,3>();
+ test<5,5,4>();
+
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/scalar_cast_m_test.cpp b/src/boost/libs/qvm/test/scalar_cast_m_test.cpp
new file mode 100644
index 000000000..78d076a0b
--- /dev/null
+++ b/src/boost/libs/qvm/test/scalar_cast_m_test.cpp
@@ -0,0 +1,34 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/mat_operations.hpp>
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Rows,int Cols>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::matrix<M1,Rows,Cols,double> x(42,1);
+ test_qvm::matrix<M1,Rows,Cols,float> y;
+ assign(y,scalar_cast<float>(x));
+ for( int i=0; i!=Rows; ++i )
+ for( int j=0; j!=Cols; ++j )
+ y.b[i][j]=static_cast<float>(x.a[i][j]);
+ BOOST_QVM_TEST_EQ(y.a,y.b);
+ }
+ }
+
+int
+main()
+ {
+ test<1,2>();
+ test<2,1>();
+ test<2,2>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/scalar_cast_q_test.cpp b/src/boost/libs/qvm/test/scalar_cast_q_test.cpp
new file mode 100644
index 000000000..ef70e3821
--- /dev/null
+++ b/src/boost/libs/qvm/test/scalar_cast_q_test.cpp
@@ -0,0 +1,30 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/quat_operations.hpp>
+#include "test_qvm_quaternion.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::quaternion<Q1,double> x(42,1);
+ test_qvm::quaternion<Q1,float> y;
+ assign(y,scalar_cast<float>(x));
+ for( int i=0; i!=4; ++i )
+ y.b[i]=static_cast<float>(x.a[i]);
+ BOOST_QVM_TEST_EQ(y.a,y.b);
+ }
+ }
+
+int
+main()
+ {
+ test();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/scalar_cast_v_test.cpp b/src/boost/libs/qvm/test/scalar_cast_v_test.cpp
new file mode 100644
index 000000000..73555a25f
--- /dev/null
+++ b/src/boost/libs/qvm/test/scalar_cast_v_test.cpp
@@ -0,0 +1,31 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_operations.hpp>
+#include "test_qvm_vector.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Dim>
+ void
+ test()
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::vector<V1,Dim,double> x(42,1);
+ test_qvm::vector<V1,Dim,float> y;
+ assign(y,scalar_cast<float>(x));
+ for( int i=0; i!=Dim; ++i )
+ y.b[i]=static_cast<float>(x.a[i]);
+ BOOST_QVM_TEST_EQ(y.a,y.b);
+ }
+ }
+
+int
+main()
+ {
+ test<2>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/scalar_traits_test.cpp b/src/boost/libs/qvm/test/scalar_traits_test.cpp
new file mode 100644
index 000000000..b419cdeeb
--- /dev/null
+++ b/src/boost/libs/qvm/test/scalar_traits_test.cpp
@@ -0,0 +1,35 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/scalar_traits.hpp>
+#include <boost/qvm/vec.hpp>
+#include <boost/qvm/mat.hpp>
+#include <boost/qvm/quat.hpp>
+
+template <bool>
+struct tester;
+
+template <>
+struct
+tester<true>
+ {
+ };
+
+using namespace boost::qvm;
+tester<is_scalar<char>::value> t1;
+tester<is_scalar<signed char>::value> t2;
+tester<is_scalar<unsigned char>::value> t3;
+tester<is_scalar<signed short>::value> t4;
+tester<is_scalar<unsigned short>::value> t5;
+tester<is_scalar<signed int>::value> t6;
+tester<is_scalar<unsigned int>::value> t7;
+tester<is_scalar<signed long>::value> t8;
+tester<is_scalar<unsigned long>::value> t9;
+tester<is_scalar<float>::value> t10;
+tester<is_scalar<double>::value> t11;
+tester<is_scalar<long double>::value> t13;
+tester<!is_scalar<vec<float,4> >::value> t14;
+tester<!is_scalar<mat<float,4,4> >::value> t15;
+tester<!is_scalar<quat<float> >::value> t16;
diff --git a/src/boost/libs/qvm/test/slerp_test.cpp b/src/boost/libs/qvm/test/slerp_test.cpp
new file mode 100644
index 000000000..c0914af30
--- /dev/null
+++ b/src/boost/libs/qvm/test/slerp_test.cpp
@@ -0,0 +1,57 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/quat_operations.hpp>
+#include <boost/qvm/quat.hpp>
+#include "test_qvm_quaternion.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ {
+ test_qvm::quaternion<Q1> a=rotx_quat(1.0f);
+ test_qvm::quaternion<Q1> b=rotx_quat(.5f);
+ test_qvm::quaternion<Q1> aa=slerp(a,b,0);
+ test_qvm::quaternion<Q1> bb=slerp(a,b,1);
+ BOOST_QVM_TEST_CLOSE(aa.a,a.a,0.0001f);
+ BOOST_QVM_TEST_CLOSE(bb.a,b.a,0.0001f);
+ }
+ for( float a1=0; a1<6.28f; a1+=0.3f )
+ {
+ test_qvm::quaternion<Q1> const qx1=rotx_quat(a1);
+ test_qvm::quaternion<Q1> const qy1=roty_quat(a1);
+ test_qvm::quaternion<Q1> const qz1=rotz_quat(a1);
+ for( float a2=0; a2<6.28f; a2+=0.05f )
+ {
+ test_qvm::quaternion<Q1> const qx2=rotx_quat(a2);
+ test_qvm::quaternion<Q1> const qy2=roty_quat(a2);
+ test_qvm::quaternion<Q1> const qz2=rotz_quat(a2);
+ for( float t=0; t<1; t+=0.03f )
+ {
+ test_qvm::quaternion<Q1> const qx=rotx_quat(a1*(1-t)+a2*t);
+ test_qvm::quaternion<Q1> const qy=roty_quat(a1*(1-t)+a2*t);
+ test_qvm::quaternion<Q1> const qz=rotz_quat(a1*(1-t)+a2*t);
+ test_qvm::quaternion<Q1> const qsx=slerp(qx1,qx2,t);
+ test_qvm::quaternion<Q1> const qsy=slerp(qref(qy1),qy2,t);
+ test_qvm::quaternion<Q1> const qsz=slerp(qz1,qref(qz2),t);
+ BOOST_QVM_TEST_CLOSE(qx.a,qsx.a,0.001f);
+ BOOST_QVM_TEST_CLOSE(qy.a,qsy.a,0.001f);
+ BOOST_QVM_TEST_CLOSE(qz.a,qsz.a,0.001f);
+ }
+ }
+ }
+ }
+ }
+
+int
+main()
+ {
+ test();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/swap_cols_test.cpp b/src/boost/libs/qvm/test/swap_cols_test.cpp
new file mode 100644
index 000000000..c7b40b720
--- /dev/null
+++ b/src/boost/libs/qvm/test/swap_cols_test.cpp
@@ -0,0 +1,101 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/map_mat_mat.hpp>
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/mat_traits_array.hpp>
+#include <boost/qvm/mat.hpp>
+#include "test_qvm.hpp"
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Rows,int Cols,int C1,int C2>
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ test_qvm::matrix<M1,Rows,Cols> x(42,1);
+ float r1[Rows][Cols];
+ for( int i=0; i!=Rows; ++i )
+ for( int j=0; j!=Cols; ++j )
+ r1[i][j]=x.a[i][j==C1?C2:j==C2?C1:j];
+ float r2[Rows][Cols];
+ assign(r2,swap_cols<C1,C2>(x));
+ BOOST_QVM_TEST_EQ(r1,r2);
+ swap_cols<C1,C2>(x) *= 2;
+ for( int i=0; i!=Rows; ++i )
+ for( int j=0; j!=Cols; ++j )
+ r1[i][j]=x.a[i][j==C1?C2:j==C2?C1:j];
+ assign(r2,swap_cols<C1,C2>(x));
+ BOOST_QVM_TEST_EQ(r1,r2);
+ swap_cols<C1,C2>(x)+swap_cols<C1,C2>(x);
+ -swap_cols<C1,C2>(x);
+ }
+ }
+
+int
+main()
+ {
+ test<2,2,0,0>();
+ test<2,2,0,1>();
+ test<2,2,1,0>();
+ test<2,2,1,1>();
+
+ test<3,3,0,0>();
+ test<3,3,0,1>();
+ test<3,3,0,2>();
+ test<3,3,1,0>();
+ test<3,3,1,1>();
+ test<3,3,1,2>();
+ test<3,3,2,0>();
+ test<3,3,2,1>();
+ test<3,3,2,2>();
+
+ test<4,4,0,0>();
+ test<4,4,0,1>();
+ test<4,4,0,2>();
+ test<4,4,0,3>();
+ test<4,4,1,0>();
+ test<4,4,1,1>();
+ test<4,4,1,2>();
+ test<4,4,1,3>();
+ test<4,4,2,0>();
+ test<4,4,2,1>();
+ test<4,4,2,2>();
+ test<4,4,2,3>();
+ test<4,4,3,0>();
+ test<4,4,3,1>();
+ test<4,4,3,2>();
+ test<4,4,3,3>();
+
+ test<5,5,0,0>();
+ test<5,5,0,1>();
+ test<5,5,0,2>();
+ test<5,5,0,3>();
+ test<5,5,0,4>();
+ test<5,5,1,0>();
+ test<5,5,1,1>();
+ test<5,5,1,2>();
+ test<5,5,1,3>();
+ test<5,5,1,4>();
+ test<5,5,2,0>();
+ test<5,5,2,1>();
+ test<5,5,2,2>();
+ test<5,5,2,3>();
+ test<5,5,2,4>();
+ test<5,5,3,0>();
+ test<5,5,3,1>();
+ test<5,5,3,2>();
+ test<5,5,3,3>();
+ test<5,5,3,4>();
+ test<5,5,4,0>();
+ test<5,5,4,1>();
+ test<5,5,4,2>();
+ test<5,5,4,3>();
+ test<5,5,4,4>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/swap_rows_test.cpp b/src/boost/libs/qvm/test/swap_rows_test.cpp
new file mode 100644
index 000000000..45ff0a940
--- /dev/null
+++ b/src/boost/libs/qvm/test/swap_rows_test.cpp
@@ -0,0 +1,101 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/map_mat_mat.hpp>
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/mat_traits_array.hpp>
+#include <boost/qvm/mat.hpp>
+#include "test_qvm.hpp"
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Rows,int Cols,int R1,int R2>
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ test_qvm::matrix<M1,Rows,Cols> x(42,1);
+ float r1[Rows][Cols];
+ for( int i=0; i!=Rows; ++i )
+ for( int j=0; j!=Cols; ++j )
+ r1[i][j]=x.a[i==R1?R2:i==R2?R1:i][j];
+ float r2[Rows][Cols];
+ assign(r2,swap_rows<R1,R2>(x));
+ BOOST_QVM_TEST_EQ(r1,r2);
+ swap_rows<R1,R2>(x) *= 2;
+ for( int i=0; i!=Rows; ++i )
+ for( int j=0; j!=Cols; ++j )
+ r1[i][j]=x.a[i==R1?R2:i==R2?R1:i][j];
+ assign(r2,swap_rows<R1,R2>(x));
+ BOOST_QVM_TEST_EQ(r1,r2);
+ swap_rows<R1,R2>(x)+swap_rows<R1,R2>(x);
+ -swap_rows<R1,R2>(x);
+ }
+ }
+
+int
+main()
+ {
+ test<2,2,0,0>();
+ test<2,2,0,1>();
+ test<2,2,1,0>();
+ test<2,2,1,1>();
+
+ test<3,3,0,0>();
+ test<3,3,0,1>();
+ test<3,3,0,2>();
+ test<3,3,1,0>();
+ test<3,3,1,1>();
+ test<3,3,1,2>();
+ test<3,3,2,0>();
+ test<3,3,2,1>();
+ test<3,3,2,2>();
+
+ test<4,4,0,0>();
+ test<4,4,0,1>();
+ test<4,4,0,2>();
+ test<4,4,0,3>();
+ test<4,4,1,0>();
+ test<4,4,1,1>();
+ test<4,4,1,2>();
+ test<4,4,1,3>();
+ test<4,4,2,0>();
+ test<4,4,2,1>();
+ test<4,4,2,2>();
+ test<4,4,2,3>();
+ test<4,4,3,0>();
+ test<4,4,3,1>();
+ test<4,4,3,2>();
+ test<4,4,3,3>();
+
+ test<5,5,0,0>();
+ test<5,5,0,1>();
+ test<5,5,0,2>();
+ test<5,5,0,3>();
+ test<5,5,0,4>();
+ test<5,5,1,0>();
+ test<5,5,1,1>();
+ test<5,5,1,2>();
+ test<5,5,1,3>();
+ test<5,5,1,4>();
+ test<5,5,2,0>();
+ test<5,5,2,1>();
+ test<5,5,2,2>();
+ test<5,5,2,3>();
+ test<5,5,2,4>();
+ test<5,5,3,0>();
+ test<5,5,3,1>();
+ test<5,5,3,2>();
+ test<5,5,3,3>();
+ test<5,5,3,4>();
+ test<5,5,4,0>();
+ test<5,5,4,1>();
+ test<5,5,4,2>();
+ test<5,5,4,3>();
+ test<5,5,4,4>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/swizzle2_test.cpp b/src/boost/libs/qvm/test/swizzle2_test.cpp
new file mode 100644
index 000000000..1568b160d
--- /dev/null
+++ b/src/boost/libs/qvm/test/swizzle2_test.cpp
@@ -0,0 +1,104 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_operations.hpp>
+#include <boost/qvm/vec_access.hpp>
+#include <boost/qvm/vec.hpp>
+#include <boost/qvm/swizzle.hpp>
+#include "test_qvm_vector.hpp"
+
+int
+main()
+ {
+ using namespace boost::qvm;
+ test_qvm::vector<V1,4> v1;
+ v1.a[0]=42.0f;
+ v1.a[1]=43.0f;
+ v1.a[2]=44.0f;
+ v1.a[3]=45.0f;
+ XX(v1) + XX(v1);
+ -XX(v1);
+ XX(42.0f) + XX(42.0f);
+ -XX(42.0f);
+ {
+ test_qvm::vector<V2,2> v0=X0(42.0f);
+ BOOST_TEST(v0.a[0]==42);
+ BOOST_TEST(v0.a[1]==0);
+ test_qvm::vector<V2,2> v2=_1X(42.0f);
+ BOOST_TEST(v2.a[0]==1);
+ BOOST_TEST(v2.a[1]==42);
+ float s=42.0f;
+ BOOST_TEST(&X(X1(s))==&s);
+ }
+ {
+ test_qvm::vector<V2,2> r;
+ r.a[0]=v1.a[0];
+ r.a[1]=v1.a[0];
+ test_qvm::vector<V2,2> v2=XX(v1);
+ BOOST_QVM_TEST_EQ(v2,r);
+ }
+ {
+ test_qvm::vector<V2,2> r;
+ r.a[0]=v1.a[0];
+ r.a[1]=v1.a[1];
+ test_qvm::vector<V2,2> v2=XY(v1);
+ BOOST_QVM_TEST_EQ(v2,r);
+ }
+ {
+ test_qvm::vector<V2,2> r;
+ r.a[0]=v1.a[0];
+ r.a[1]=v1.a[2];
+ test_qvm::vector<V2,2> v2=XZ(v1);
+ BOOST_QVM_TEST_EQ(v2,r);
+ }
+ {
+ test_qvm::vector<V2,2> r;
+ r.a[0]=v1.a[0];
+ r.a[1]=v1.a[3];
+ test_qvm::vector<V2,2> v2=XW(v1);
+ BOOST_QVM_TEST_EQ(v2,r);
+ }
+ {
+ test_qvm::vector<V2,2> r;
+ r.a[0]=v1.a[0];
+ r.a[1]=0;
+ test_qvm::vector<V2,2> v2=X0(v1);
+ BOOST_QVM_TEST_EQ(v2,r);
+ }
+ {
+ test_qvm::vector<V2,2> r;
+ r.a[0]=v1.a[0];
+ r.a[1]=1;
+ test_qvm::vector<V2,2> v2=X1(v1);
+ BOOST_QVM_TEST_EQ(v2,r);
+ }
+ {
+ test_qvm::vector<V2,2> v2=XY(v1);
+ test_qvm::vector<V3,2> v3;
+ XY(v3)=XY(v2);
+ BOOST_QVM_TEST_EQ(v2,v3);
+ }
+ {
+ test_qvm::vector<V1,2> v=_00();
+ BOOST_TEST(v.a[0]==0);
+ BOOST_TEST(v.a[1]==0);
+ }
+ {
+ test_qvm::vector<V1,2> v=_01();
+ BOOST_TEST(v.a[0]==0);
+ BOOST_TEST(v.a[1]==1);
+ }
+ {
+ test_qvm::vector<V1,2> v=_10();
+ BOOST_TEST(v.a[0]==1);
+ BOOST_TEST(v.a[1]==0);
+ }
+ {
+ test_qvm::vector<V1,2> v=_11();
+ BOOST_TEST(v.a[0]==1);
+ BOOST_TEST(v.a[1]==1);
+ }
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/swizzle2_test2.cpp b/src/boost/libs/qvm/test/swizzle2_test2.cpp
new file mode 100644
index 000000000..837026e62
--- /dev/null
+++ b/src/boost/libs/qvm/test/swizzle2_test2.cpp
@@ -0,0 +1,49 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_traits.hpp>
+#include <boost/qvm/swizzle2.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+template <int D> struct my_vec { };
+int called=0;
+
+namespace
+boost
+ {
+ namespace
+ qvm
+ {
+ void
+ XX(...)
+ {
+ BOOST_TEST(0);
+ }
+ void
+ XY(...)
+ {
+ ++called;
+ }
+ template <int D>
+ struct
+ vec_traits< my_vec<D> >
+ {
+ typedef int scalar_type;
+ static int const dim=D;
+ template <int I> static int read_element( my_vec<D> const & );
+ template <int I> static int & write_element( my_vec<D> & );
+ };
+ }
+ }
+
+int
+main()
+ {
+ using namespace boost::qvm;
+ XX(my_vec<1>());
+ XY(my_vec<1>());
+ BOOST_TEST(called==1);
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/swizzle2_test3.cpp b/src/boost/libs/qvm/test/swizzle2_test3.cpp
new file mode 100644
index 000000000..a9c02b68c
--- /dev/null
+++ b/src/boost/libs/qvm/test/swizzle2_test3.cpp
@@ -0,0 +1,49 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_traits.hpp>
+#include <boost/qvm/swizzle2.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+template <int D> struct my_vec { };
+int called=0;
+
+namespace
+boost
+ {
+ namespace
+ qvm
+ {
+ void
+ YY(...)
+ {
+ BOOST_TEST(0);
+ }
+ void
+ XZ(...)
+ {
+ ++called;
+ }
+ template <int D>
+ struct
+ vec_traits< my_vec<D> >
+ {
+ typedef int scalar_type;
+ static int const dim=D;
+ template <int I> static int read_element( my_vec<D> const & );
+ template <int I> static int & write_element( my_vec<D> & );
+ };
+ }
+ }
+
+int
+main()
+ {
+ using namespace boost::qvm;
+ YY(my_vec<2>());
+ XZ(my_vec<2>());
+ BOOST_TEST(called==1);
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/swizzle2_test4.cpp b/src/boost/libs/qvm/test/swizzle2_test4.cpp
new file mode 100644
index 000000000..2b8f63f6a
--- /dev/null
+++ b/src/boost/libs/qvm/test/swizzle2_test4.cpp
@@ -0,0 +1,49 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_traits.hpp>
+#include <boost/qvm/swizzle2.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+template <int D> struct my_vec { };
+int called=0;
+
+namespace
+boost
+ {
+ namespace
+ qvm
+ {
+ void
+ ZZ(...)
+ {
+ BOOST_TEST(0);
+ }
+ void
+ XW(...)
+ {
+ ++called;
+ }
+ template <int D>
+ struct
+ vec_traits< my_vec<D> >
+ {
+ typedef int scalar_type;
+ static int const dim=D;
+ template <int I> static int read_element( my_vec<D> const & );
+ template <int I> static int & write_element( my_vec<D> & );
+ };
+ }
+ }
+
+int
+main()
+ {
+ using namespace boost::qvm;
+ ZZ(my_vec<3>());
+ XW(my_vec<3>());
+ BOOST_TEST(called==1);
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/swizzle3_test.cpp b/src/boost/libs/qvm/test/swizzle3_test.cpp
new file mode 100644
index 000000000..5a922b13b
--- /dev/null
+++ b/src/boost/libs/qvm/test/swizzle3_test.cpp
@@ -0,0 +1,147 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_operations.hpp>
+#include <boost/qvm/vec_access.hpp>
+#include <boost/qvm/vec.hpp>
+#include <boost/qvm/swizzle.hpp>
+#include "test_qvm_vector.hpp"
+
+int
+main()
+ {
+ using namespace boost::qvm;
+ test_qvm::vector<V1,4> v1;
+ v1.a[0]=42.0f;
+ v1.a[1]=43.0f;
+ v1.a[2]=44.0f;
+ v1.a[3]=45.0f;
+ XXX(v1) + XXX(v1);
+ -XXX(v1);
+ XXX(42.0f) + XXX(42.0f);
+ -XXX(42.0f);
+ {
+ test_qvm::vector<V2,3> v0=X00(42.0f);
+ BOOST_TEST(v0.a[0]==42);
+ BOOST_TEST(v0.a[1]==0);
+ BOOST_TEST(v0.a[2]==0);
+ test_qvm::vector<V2,3> v2=_10X(42.0f);
+ BOOST_TEST(v2.a[0]==1);
+ BOOST_TEST(v2.a[1]==0);
+ BOOST_TEST(v2.a[2]==42);
+ float s=42.0f;
+ BOOST_TEST(&X(X01(s))==&s);
+ }
+ {
+ test_qvm::vector<V2,3> r;
+ r.a[0]=v1.a[0];
+ r.a[1]=v1.a[0];
+ r.a[2]=v1.a[0];
+ test_qvm::vector<V2,3> v2=XXX(v1);
+ BOOST_QVM_TEST_EQ(v2,r);
+ }
+ {
+ test_qvm::vector<V2,3> r;
+ r.a[0]=v1.a[0];
+ r.a[1]=v1.a[0];
+ r.a[2]=v1.a[1];
+ test_qvm::vector<V2,3> v2=XXY(v1);
+ BOOST_QVM_TEST_EQ(v2,r);
+ }
+ {
+ test_qvm::vector<V2,3> r;
+ r.a[0]=v1.a[0];
+ r.a[1]=v1.a[0];
+ r.a[2]=v1.a[2];
+ test_qvm::vector<V2,3> v2=XXZ(v1);
+ BOOST_QVM_TEST_EQ(v2,r);
+ }
+ {
+ test_qvm::vector<V2,3> r;
+ r.a[0]=v1.a[0];
+ r.a[1]=v1.a[0];
+ r.a[2]=v1.a[3];
+ test_qvm::vector<V2,3> v2=XXW(v1);
+ BOOST_QVM_TEST_EQ(v2,r);
+ }
+ {
+ test_qvm::vector<V2,3> r;
+ r.a[0]=v1.a[0];
+ r.a[1]=v1.a[0];
+ r.a[2]=0;
+ test_qvm::vector<V2,3> v2=XX0(v1);
+ BOOST_QVM_TEST_EQ(v2,r);
+ }
+ {
+ test_qvm::vector<V2,3> r;
+ r.a[0]=v1.a[0];
+ r.a[1]=v1.a[0];
+ r.a[2]=1;
+ test_qvm::vector<V2,3> v2=XX1(v1);
+ BOOST_QVM_TEST_EQ(v2,r);
+ }
+ {
+ test_qvm::vector<V2,3> v2=XYZ(v1);
+ XYZ(v1) *= 2;
+ v2 *= 2;
+ test_qvm::vector<V2,3> v3=XYZ(v1);
+ BOOST_QVM_TEST_EQ(v2,v3);
+ }
+ {
+ test_qvm::vector<V2,3> v2=XYZ(v1);
+ test_qvm::vector<V3,3> v3;
+ XYZ(v3)=XYZ(v2);
+ BOOST_QVM_TEST_EQ(v2,v3);
+ }
+ {
+ test_qvm::vector<V1,3> v=_000();
+ BOOST_TEST(v.a[0]==0);
+ BOOST_TEST(v.a[1]==0);
+ BOOST_TEST(v.a[2]==0);
+ }
+ {
+ test_qvm::vector<V1,3> v=_001();
+ BOOST_TEST(v.a[0]==0);
+ BOOST_TEST(v.a[1]==0);
+ BOOST_TEST(v.a[2]==1);
+ }
+ {
+ test_qvm::vector<V1,3> v=_010();
+ BOOST_TEST(v.a[0]==0);
+ BOOST_TEST(v.a[1]==1);
+ BOOST_TEST(v.a[2]==0);
+ }
+ {
+ test_qvm::vector<V1,3> v=_011();
+ BOOST_TEST(v.a[0]==0);
+ BOOST_TEST(v.a[1]==1);
+ BOOST_TEST(v.a[2]==1);
+ }
+ {
+ test_qvm::vector<V1,3> v=_100();
+ BOOST_TEST(v.a[0]==1);
+ BOOST_TEST(v.a[1]==0);
+ BOOST_TEST(v.a[2]==0);
+ }
+ {
+ test_qvm::vector<V1,3> v=_101();
+ BOOST_TEST(v.a[0]==1);
+ BOOST_TEST(v.a[1]==0);
+ BOOST_TEST(v.a[2]==1);
+ }
+ {
+ test_qvm::vector<V1,3> v=_110();
+ BOOST_TEST(v.a[0]==1);
+ BOOST_TEST(v.a[1]==1);
+ BOOST_TEST(v.a[2]==0);
+ }
+ {
+ test_qvm::vector<V1,3> v=_111();
+ BOOST_TEST(v.a[0]==1);
+ BOOST_TEST(v.a[1]==1);
+ BOOST_TEST(v.a[2]==1);
+ }
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/swizzle3_test2.cpp b/src/boost/libs/qvm/test/swizzle3_test2.cpp
new file mode 100644
index 000000000..cfc91f0f4
--- /dev/null
+++ b/src/boost/libs/qvm/test/swizzle3_test2.cpp
@@ -0,0 +1,49 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_traits.hpp>
+#include <boost/qvm/swizzle3.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+template <int D> struct my_vec { };
+int called=0;
+
+namespace
+boost
+ {
+ namespace
+ qvm
+ {
+ void
+ XXX(...)
+ {
+ BOOST_TEST(0);
+ }
+ void
+ XXY(...)
+ {
+ ++called;
+ }
+ template <int D>
+ struct
+ vec_traits< my_vec<D> >
+ {
+ typedef int scalar_type;
+ static int const dim=D;
+ template <int I> static int read_element( my_vec<D> const & );
+ template <int I> static int & write_element( my_vec<D> & );
+ };
+ }
+ }
+
+int
+main()
+ {
+ using namespace boost::qvm;
+ XXX(my_vec<1>());
+ XXY(my_vec<1>());
+ BOOST_TEST(called==1);
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/swizzle3_test3.cpp b/src/boost/libs/qvm/test/swizzle3_test3.cpp
new file mode 100644
index 000000000..006f1138f
--- /dev/null
+++ b/src/boost/libs/qvm/test/swizzle3_test3.cpp
@@ -0,0 +1,49 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_traits.hpp>
+#include <boost/qvm/swizzle3.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+template <int D> struct my_vec { };
+int called=0;
+
+namespace
+boost
+ {
+ namespace
+ qvm
+ {
+ void
+ YYY(...)
+ {
+ BOOST_TEST(0);
+ }
+ void
+ XXZ(...)
+ {
+ ++called;
+ }
+ template <int D>
+ struct
+ vec_traits< my_vec<D> >
+ {
+ typedef int scalar_type;
+ static int const dim=D;
+ template <int I> static int read_element( my_vec<D> const & );
+ template <int I> static int & write_element( my_vec<D> & );
+ };
+ }
+ }
+
+int
+main()
+ {
+ using namespace boost::qvm;
+ YYY(my_vec<2>());
+ XXZ(my_vec<2>());
+ BOOST_TEST(called==1);
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/swizzle3_test4.cpp b/src/boost/libs/qvm/test/swizzle3_test4.cpp
new file mode 100644
index 000000000..bba231a1c
--- /dev/null
+++ b/src/boost/libs/qvm/test/swizzle3_test4.cpp
@@ -0,0 +1,49 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_traits.hpp>
+#include <boost/qvm/swizzle3.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+template <int D> struct my_vec { };
+int called=0;
+
+namespace
+boost
+ {
+ namespace
+ qvm
+ {
+ void
+ ZZZ(...)
+ {
+ BOOST_TEST(0);
+ }
+ void
+ XXW(...)
+ {
+ ++called;
+ }
+ template <int D>
+ struct
+ vec_traits< my_vec<D> >
+ {
+ typedef int scalar_type;
+ static int const dim=D;
+ template <int I> static int read_element( my_vec<D> const & );
+ template <int I> static int & write_element( my_vec<D> & );
+ };
+ }
+ }
+
+int
+main()
+ {
+ using namespace boost::qvm;
+ ZZZ(my_vec<3>());
+ XXW(my_vec<3>());
+ BOOST_TEST(called==1);
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/swizzle4_test.cpp b/src/boost/libs/qvm/test/swizzle4_test.cpp
new file mode 100644
index 000000000..59c9bfcbf
--- /dev/null
+++ b/src/boost/libs/qvm/test/swizzle4_test.cpp
@@ -0,0 +1,219 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_operations.hpp>
+#include <boost/qvm/vec_access.hpp>
+#include <boost/qvm/vec.hpp>
+#include <boost/qvm/swizzle.hpp>
+#include "test_qvm_vector.hpp"
+
+int
+main()
+ {
+ using namespace boost::qvm;
+ test_qvm::vector<V1,4> v1;
+ v1.a[0]=42.0f;
+ v1.a[1]=43.0f;
+ v1.a[2]=44.0f;
+ v1.a[3]=45.0f;
+ XXXX(v1) + XXXX(v1);
+ -XXXX(v1);
+ XXXX(42.0f) + XXXX(42.0f);
+ -XXXX(42.0f);
+ {
+ test_qvm::vector<V2,4> v0=X001(42.0f);
+ BOOST_TEST(v0.a[0]==42);
+ BOOST_TEST(v0.a[1]==0);
+ BOOST_TEST(v0.a[2]==0);
+ BOOST_TEST(v0.a[3]==1);
+ test_qvm::vector<V2,4> v2=_100X(42.0f);
+ BOOST_TEST(v2.a[0]==1);
+ BOOST_TEST(v2.a[1]==0);
+ BOOST_TEST(v2.a[2]==0);
+ BOOST_TEST(v2.a[3]==42);
+ float s=42.0f;
+ BOOST_TEST(&X(X101(s))==&s);
+ }
+ {
+ test_qvm::vector<V2,4> r;
+ r.a[0]=v1.a[0];
+ r.a[1]=v1.a[0];
+ r.a[2]=v1.a[0];
+ r.a[3]=v1.a[0];
+ test_qvm::vector<V2,4> v2=XXXX(v1);
+ BOOST_QVM_TEST_EQ(v2,r);
+ }
+ {
+ test_qvm::vector<V2,4> r;
+ r.a[0]=v1.a[0];
+ r.a[1]=v1.a[0];
+ r.a[2]=v1.a[0];
+ r.a[3]=v1.a[1];
+ test_qvm::vector<V2,4> v2=XXXY(v1);
+ BOOST_QVM_TEST_EQ(v2,r);
+ }
+ {
+ test_qvm::vector<V2,4> r;
+ r.a[0]=v1.a[0];
+ r.a[1]=v1.a[0];
+ r.a[2]=v1.a[0];
+ r.a[3]=v1.a[2];
+ test_qvm::vector<V2,4> v2=XXXZ(v1);
+ BOOST_QVM_TEST_EQ(v2,r);
+ }
+ {
+ test_qvm::vector<V2,4> r;
+ r.a[0]=v1.a[0];
+ r.a[1]=v1.a[0];
+ r.a[2]=v1.a[0];
+ r.a[3]=v1.a[3];
+ test_qvm::vector<V2,4> v2=XXXW(v1);
+ BOOST_QVM_TEST_EQ(v2,r);
+ }
+ {
+ test_qvm::vector<V2,4> r;
+ r.a[0]=v1.a[0];
+ r.a[1]=v1.a[0];
+ r.a[2]=v1.a[0];
+ r.a[3]=0;
+ test_qvm::vector<V2,4> v2=XXX0(v1);
+ BOOST_QVM_TEST_EQ(v2,r);
+ }
+ {
+ test_qvm::vector<V2,4> r;
+ r.a[0]=v1.a[0];
+ r.a[1]=v1.a[0];
+ r.a[2]=v1.a[0];
+ r.a[3]=1;
+ test_qvm::vector<V2,4> v2=XXX1(v1);
+ BOOST_QVM_TEST_EQ(v2,r);
+ }
+ {
+ test_qvm::vector<V2,4> v2=XYZW(v1);
+ XYZW(v1) *= 2;
+ v2 *= 2;
+ test_qvm::vector<V2,4> v3=XYZW(v1);
+ BOOST_QVM_TEST_EQ(v2,v3);
+ }
+ {
+ test_qvm::vector<V2,4> v2=XYZW(v1);
+ test_qvm::vector<V3,4> v3;
+ XYZW(v3)=XYZW(v2);
+ BOOST_QVM_TEST_EQ(v2,v3);
+ }
+ {
+ test_qvm::vector<V1,4> v=_0000();
+ BOOST_TEST(v.a[0]==0);
+ BOOST_TEST(v.a[1]==0);
+ BOOST_TEST(v.a[2]==0);
+ BOOST_TEST(v.a[3]==0);
+ }
+ {
+ test_qvm::vector<V1,4> v=_0001();
+ BOOST_TEST(v.a[0]==0);
+ BOOST_TEST(v.a[1]==0);
+ BOOST_TEST(v.a[2]==0);
+ BOOST_TEST(v.a[3]==1);
+ }
+ {
+ test_qvm::vector<V1,4> v=_0010();
+ BOOST_TEST(v.a[0]==0);
+ BOOST_TEST(v.a[1]==0);
+ BOOST_TEST(v.a[2]==1);
+ BOOST_TEST(v.a[3]==0);
+ }
+ {
+ test_qvm::vector<V1,4> v=_0011();
+ BOOST_TEST(v.a[0]==0);
+ BOOST_TEST(v.a[1]==0);
+ BOOST_TEST(v.a[2]==1);
+ BOOST_TEST(v.a[3]==1);
+ }
+ {
+ test_qvm::vector<V1,4> v=_0100();
+ BOOST_TEST(v.a[0]==0);
+ BOOST_TEST(v.a[1]==1);
+ BOOST_TEST(v.a[2]==0);
+ BOOST_TEST(v.a[3]==0);
+ }
+ {
+ test_qvm::vector<V1,4> v=_0101();
+ BOOST_TEST(v.a[0]==0);
+ BOOST_TEST(v.a[1]==1);
+ BOOST_TEST(v.a[2]==0);
+ BOOST_TEST(v.a[3]==1);
+ }
+ {
+ test_qvm::vector<V1,4> v=_0110();
+ BOOST_TEST(v.a[0]==0);
+ BOOST_TEST(v.a[1]==1);
+ BOOST_TEST(v.a[2]==1);
+ BOOST_TEST(v.a[3]==0);
+ }
+ {
+ test_qvm::vector<V1,4> v=_0111();
+ BOOST_TEST(v.a[0]==0);
+ BOOST_TEST(v.a[1]==1);
+ BOOST_TEST(v.a[2]==1);
+ BOOST_TEST(v.a[3]==1);
+ }
+ {
+ test_qvm::vector<V1,4> v=_1000();
+ BOOST_TEST(v.a[0]==1);
+ BOOST_TEST(v.a[1]==0);
+ BOOST_TEST(v.a[2]==0);
+ BOOST_TEST(v.a[3]==0);
+ }
+ {
+ test_qvm::vector<V1,4> v=_1001();
+ BOOST_TEST(v.a[0]==1);
+ BOOST_TEST(v.a[1]==0);
+ BOOST_TEST(v.a[2]==0);
+ BOOST_TEST(v.a[3]==1);
+ }
+ {
+ test_qvm::vector<V1,4> v=_1010();
+ BOOST_TEST(v.a[0]==1);
+ BOOST_TEST(v.a[1]==0);
+ BOOST_TEST(v.a[2]==1);
+ BOOST_TEST(v.a[3]==0);
+ }
+ {
+ test_qvm::vector<V1,4> v=_1011();
+ BOOST_TEST(v.a[0]==1);
+ BOOST_TEST(v.a[1]==0);
+ BOOST_TEST(v.a[2]==1);
+ BOOST_TEST(v.a[3]==1);
+ }
+ {
+ test_qvm::vector<V1,4> v=_1100();
+ BOOST_TEST(v.a[0]==1);
+ BOOST_TEST(v.a[1]==1);
+ BOOST_TEST(v.a[2]==0);
+ BOOST_TEST(v.a[3]==0);
+ }
+ {
+ test_qvm::vector<V1,4> v=_1101();
+ BOOST_TEST(v.a[0]==1);
+ BOOST_TEST(v.a[1]==1);
+ BOOST_TEST(v.a[2]==0);
+ BOOST_TEST(v.a[3]==1);
+ }
+ {
+ test_qvm::vector<V1,4> v=_1110();
+ BOOST_TEST(v.a[0]==1);
+ BOOST_TEST(v.a[1]==1);
+ BOOST_TEST(v.a[2]==1);
+ BOOST_TEST(v.a[3]==0);
+ }
+ {
+ test_qvm::vector<V1,4> v=_1111();
+ BOOST_TEST(v.a[0]==1);
+ BOOST_TEST(v.a[1]==1);
+ BOOST_TEST(v.a[2]==1);
+ BOOST_TEST(v.a[3]==1);
+ }
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/swizzle4_test2.cpp b/src/boost/libs/qvm/test/swizzle4_test2.cpp
new file mode 100644
index 000000000..049d59917
--- /dev/null
+++ b/src/boost/libs/qvm/test/swizzle4_test2.cpp
@@ -0,0 +1,49 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_traits.hpp>
+#include <boost/qvm/swizzle4.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+template <int D> struct my_vec { };
+int called=0;
+
+namespace
+boost
+ {
+ namespace
+ qvm
+ {
+ void
+ XXXX(...)
+ {
+ BOOST_TEST(0);
+ }
+ void
+ XXXY(...)
+ {
+ ++called;
+ }
+ template <int D>
+ struct
+ vec_traits< my_vec<D> >
+ {
+ typedef int scalar_type;
+ static int const dim=D;
+ template <int I> static int read_element( my_vec<D> const & );
+ template <int I> static int & write_element( my_vec<D> & );
+ };
+ }
+ }
+
+int
+main()
+ {
+ using namespace boost::qvm;
+ XXXX(my_vec<1>());
+ XXXY(my_vec<1>());
+ BOOST_TEST(called==1);
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/swizzle4_test3.cpp b/src/boost/libs/qvm/test/swizzle4_test3.cpp
new file mode 100644
index 000000000..ac472b2dc
--- /dev/null
+++ b/src/boost/libs/qvm/test/swizzle4_test3.cpp
@@ -0,0 +1,49 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_traits.hpp>
+#include <boost/qvm/swizzle4.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+template <int D> struct my_vec { };
+int called=0;
+
+namespace
+boost
+ {
+ namespace
+ qvm
+ {
+ void
+ YYYY(...)
+ {
+ BOOST_TEST(0);
+ }
+ void
+ XXXZ(...)
+ {
+ ++called;
+ }
+ template <int D>
+ struct
+ vec_traits< my_vec<D> >
+ {
+ typedef int scalar_type;
+ static int const dim=D;
+ template <int I> static int read_element( my_vec<D> const & );
+ template <int I> static int & write_element( my_vec<D> & );
+ };
+ }
+ }
+
+int
+main()
+ {
+ using namespace boost::qvm;
+ YYYY(my_vec<2>());
+ XXXZ(my_vec<2>());
+ BOOST_TEST(called==1);
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/swizzle4_test4.cpp b/src/boost/libs/qvm/test/swizzle4_test4.cpp
new file mode 100644
index 000000000..7b191563d
--- /dev/null
+++ b/src/boost/libs/qvm/test/swizzle4_test4.cpp
@@ -0,0 +1,49 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_traits.hpp>
+#include <boost/qvm/swizzle4.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+template <int D> struct my_vec { };
+int called=0;
+
+namespace
+boost
+ {
+ namespace
+ qvm
+ {
+ void
+ ZZZZ(...)
+ {
+ BOOST_TEST(0);
+ }
+ void
+ XXXW(...)
+ {
+ ++called;
+ }
+ template <int D>
+ struct
+ vec_traits< my_vec<D> >
+ {
+ typedef int scalar_type;
+ static int const dim=D;
+ template <int I> static int read_element( my_vec<D> const & );
+ template <int I> static int & write_element( my_vec<D> & );
+ };
+ }
+ }
+
+int
+main()
+ {
+ using namespace boost::qvm;
+ ZZZZ(my_vec<3>());
+ XXXW(my_vec<3>());
+ BOOST_TEST(called==1);
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/swizzle_const_fail.cpp b/src/boost/libs/qvm/test/swizzle_const_fail.cpp
new file mode 100644
index 000000000..df3d77c9d
--- /dev/null
+++ b/src/boost/libs/qvm/test/swizzle_const_fail.cpp
@@ -0,0 +1,18 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec.hpp>
+#include <boost/qvm/vec_operations.hpp>
+#include <boost/qvm/swizzle2.hpp>
+
+int
+main()
+ {
+ using namespace boost::qvm;
+ vec<float,2> v;
+ vec<float,2> const & cv=v;
+ XY(cv)*=2;
+ return 1;
+ }
diff --git a/src/boost/libs/qvm/test/test_qvm.hpp b/src/boost/libs/qvm/test/test_qvm.hpp
new file mode 100644
index 000000000..f9c000c0c
--- /dev/null
+++ b/src/boost/libs/qvm/test/test_qvm.hpp
@@ -0,0 +1,257 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_QVM_06E5D36EB6C211DEA317E19C55D89593
+#define BOOST_QVM_06E5D36EB6C211DEA317E19C55D89593
+
+#include <boost/test/tools/floating_point_comparison.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <iostream>
+
+#define BOOST_QVM_TEST_EQ(expra,exprb) ( ::test_qvm::detail::test_eq_impl(#expra, #exprb, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expra, exprb) )
+#define BOOST_QVM_TEST_NEQ(expra,exprb) ( ::test_qvm::detail::test_neq_impl(#expra, #exprb, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expra, exprb) )
+#define BOOST_QVM_TEST_CLOSE(expra,exprb,exprt) ( ::test_qvm::detail::test_close_impl(#expra, #exprb, #exprt, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expra, exprb, exprt) )
+
+#define BOOST_QVM_TEST_EQ_QUAT(expra,exprb) ( ::test_qvm::detail::test_eq_q_impl(#expra, #exprb, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expra, exprb) )
+#define BOOST_QVM_TEST_NEQ_QUAT(expra,exprb) ( ::test_qvm::detail::test_neq_q_impl(#expra, #exprb, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expra, exprb) )
+#define BOOST_QVM_TEST_CLOSE_QUAT(expra,exprb,exprt) ( ::test_qvm::detail::test_close_q_impl(#expra, #exprb, #exprt, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expra, exprb, exprt) )
+
+namespace
+test_qvm
+ {
+ namespace
+ detail
+ {
+ inline
+ bool
+ close_at_tolerance( float a, float b, float tolerance )
+ {
+ return boost::math::fpc::close_at_tolerance<float>(tolerance,boost::math::fpc::FPC_STRONG)(a,b);
+ }
+
+ inline
+ bool
+ close_at_tolerance( double a, double b, double tolerance )
+ {
+ return boost::math::fpc::close_at_tolerance<double>(tolerance,boost::math::fpc::FPC_STRONG)(a,b);
+ }
+
+ template <class A,class B>
+ void
+ dump_ab( A a, B b )
+ {
+ std::cerr << a << '\t' << b << std::endl;
+ }
+
+ template <class A,class B,int D>
+ void
+ dump_ab( A (&a)[D], B (&b)[D] )
+ {
+ for( int i=0; i!=D; ++i )
+ dump_ab(a[i],b[i]);
+ }
+
+ template <class A,class B>
+ void
+ test_eq_impl( char const * expra, char const * exprb, char const * file, int line, char const * function, A a, B b )
+ {
+ using namespace ::boost::qvm;
+ if( !(a==b) )
+ {
+ std::cerr << file << "(" << line << "): BOOST_QVM_TEST_EQ(" << expra << ',' << exprb
+ << ") failed in function " << function << '\n';
+ dump_ab(a,b);
+ ++::boost::detail::test_errors();
+ }
+ }
+
+ template <class A,class B,int M,int N>
+ void
+ test_eq_impl( char const * expra, char const * exprb, char const * file, int line, char const * function, A (&a)[M][N], B (&b)[M][N] )
+ {
+ using namespace ::boost::qvm;
+ for( int i=0; i<M; ++i )
+ for( int j=0; j<N; ++j )
+ if( !(a[i][j]==b[i][j]) )
+ {
+ std::cerr << file << "(" << line << "): BOOST_QVM_TEST_EQ(" << expra << ',' << exprb
+ << ") failed in function " << function << '\n';
+ dump_ab(a,b);
+ ++::boost::detail::test_errors();
+ return;
+ }
+ }
+
+ template <class A,class B,int D>
+ void
+ test_eq_impl( char const * expra, char const * exprb, char const * file, int line, char const * function, A (&a)[D], B (&b)[D] )
+ {
+ using namespace ::boost::qvm;
+ for( int i=0; i<D; ++i )
+ if( !(a[i]==b[i]) )
+ {
+ std::cerr << file << "(" << line << "): BOOST_QVM_TEST_EQ" << expra << ',' << exprb
+ << ") failed in function " << function <<'\n';
+ dump_ab(a,b);
+ ++::boost::detail::test_errors();
+ return;
+ }
+ }
+
+ template <class A,class B>
+ void
+ test_eq_q_impl( char const * expra, char const * exprb, char const * file, int line, char const * function, A (&a)[4], B (&b)[4] )
+ {
+ using namespace ::boost::qvm;
+ int i;
+ for( i=0; i<4; ++i )
+ if( !(a[i]==b[i]) )
+ break;
+ if( i==4 )
+ return;
+ for( i=0; i<4; ++i )
+ if( !(a[i]==-b[i]) )
+ {
+ std::cerr << file << "(" << line << "): BOOST_QVM_TEST_EQ" << expra << ',' << exprb
+ << ") failed in function " << function <<'\n';
+ dump_ab(a,b);
+ ++::boost::detail::test_errors();
+ return;
+ }
+ }
+
+ template <class A,class B>
+ void
+ test_neq_impl( char const * expra, char const * exprb, char const * file, int line, char const * function, A a, B b )
+ {
+ using namespace ::boost::qvm;
+ if( !(a!=b) )
+ {
+ std::cerr << file << "(" << line << "): BOOST_QVM_TEST_NEQ(" << expra << ',' << exprb
+ << ") failed in function " << function << '\n';
+ dump_ab(a,b);
+ ++::boost::detail::test_errors();
+ }
+ }
+
+ template <class A,class B,int M,int N>
+ void
+ test_neq_impl( char const * expra, char const * exprb, char const * file, int line, char const * function, A (&a)[M][N], B (&b)[M][N] )
+ {
+ using namespace ::boost::qvm;
+ for( int i=0; i<M; ++i )
+ for( int j=0; j<N; ++j )
+ if( a[i][j]!=b[i][j] )
+ return;
+ std::cerr << file << "(" << line << "): BOOST_QVM_TEST_NEQ(" << expra << ',' << exprb
+ << ") failed in function " << function << '\n';
+ dump_ab(a,b);
+ ++::boost::detail::test_errors();
+ }
+
+ template <class A,class B,int D>
+ void
+ test_neq_impl( char const * expra, char const * exprb, char const * file, int line, char const * function, A (&a)[D], B (&b)[D] )
+ {
+ using namespace ::boost::qvm;
+ for( int i=0; i<D; ++i )
+ if( a[i]!=b[i] )
+ return;
+ std::cerr << file << "(" << line << "): BOOST_QVM_TEST_NEQ(" << expra << ',' << exprb
+ << ") failed in function " << function << '\n';
+ dump_ab(a,b);
+ ++::boost::detail::test_errors();
+ }
+
+ template <class A,class B>
+ void
+ test_neq_q_impl( char const * expra, char const * exprb, char const * file, int line, char const * function, A (&a)[4], B (&b)[4] )
+ {
+ using namespace ::boost::qvm;
+ int i;
+ for( i=0; i<4; ++i )
+ if( !(a[i]!=b[i]) )
+ break;
+ if( i==4 )
+ return;
+ for( i=0; i<4; ++i )
+ if( !(a[i]!=-b[i]) )
+ {
+ std::cerr << file << "(" << line << "): BOOST_QVM_TEST_EQ" << expra << ',' << exprb
+ << ") failed in function " << function <<'\n';
+ dump_ab(a,b);
+ ++::boost::detail::test_errors();
+ return;
+ }
+ }
+
+ template <class A,class B,class T>
+ void
+ test_close_impl( char const * expra, char const * /*exprb*/, char const * /*exprt*/, char const * file, int line, char const * function, A a, B b, T t )
+ {
+ if( !close_at_tolerance(a,b,t) )
+ {
+ std::cerr << file << "(" << line << "): BOOST_QVM_TEST_CLOSE(" << expra << ',' << b << ',' << t
+ << ") failed in function " << function << '\n';
+ ++::boost::detail::test_errors();
+ return;
+ }
+ }
+
+ template <class A,class B,class T,int M,int N>
+ void
+ test_close_impl( char const * expra, char const * exprb, char const * exprt, char const * file, int line, char const * function, A (&a)[M][N], B (&b)[M][N], T t )
+ {
+ for( int i=0; i<M; ++i )
+ for( int j=0; j<N; ++j )
+ if( !close_at_tolerance(a[i][j],b[i][j],t) )
+ {
+ std::cerr << file << "(" << line << "): BOOST_QVM_TEST_CLOSE(" << expra << ',' << exprb << ',' << exprt
+ << ") failed in function " << function << '\n';
+ dump_ab(a,b);
+ ++::boost::detail::test_errors();
+ return;
+ }
+ }
+
+ template <class A,class B,class T,int D>
+ void
+ test_close_impl( char const * expra, char const * exprb, char const * exprt, char const * file, int line, char const * function, A (&a)[D], B (&b)[D], T t )
+ {
+ for( int i=0; i<D; ++i )
+ if( !close_at_tolerance(a[i],b[i],t) )
+ {
+ std::cerr << file << "(" << line << "): BOOST_QVM_TEST_CLOSE(" << expra << ',' << exprb << ',' << exprt
+ << ") failed in function " << function << '\n';
+ dump_ab(a,b);
+ ++::boost::detail::test_errors();
+ return;
+ }
+ }
+
+ template <class A,class B,class T>
+ void
+ test_close_q_impl( char const * expra, char const * exprb, char const * exprt, char const * file, int line, char const * function, A (&a)[4], B (&b)[4], T t )
+ {
+ int i;
+ for( i=0; i<4; ++i )
+ if( !close_at_tolerance(a[i],b[i],t) )
+ break;
+ if( i==4 )
+ return;
+ for( i=0; i<4; ++i )
+ if( !close_at_tolerance(a[i],-b[i],t) )
+ {
+ std::cerr << file << "(" << line << "): BOOST_QVM_TEST_CLOSE_QUAT(" << expra << ',' << exprb << ',' << exprt
+ << ") failed in function " << function << '\n';
+ dump_ab(a,b);
+ ++::boost::detail::test_errors();
+ return;
+ }
+ }
+ }
+ }
+
+#endif
diff --git a/src/boost/libs/qvm/test/test_qvm_matrix.hpp b/src/boost/libs/qvm/test/test_qvm_matrix.hpp
new file mode 100644
index 000000000..64c477b14
--- /dev/null
+++ b/src/boost/libs/qvm/test/test_qvm_matrix.hpp
@@ -0,0 +1,85 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_QVM_9C471450B3A611DEAF56C1F155D89593
+#define BOOST_QVM_9C471450B3A611DEAF56C1F155D89593
+
+#include <boost/qvm/mat_traits_defaults.hpp>
+#include <boost/qvm/deduce_mat.hpp>
+#include <boost/qvm/assert.hpp>
+#include "test_qvm.hpp"
+
+namespace
+test_qvm
+ {
+ template <class Tag,int Rows,int Cols,class T=float>
+ struct
+ matrix
+ {
+ T a[Rows][Cols];
+ mutable T b[Rows][Cols];
+
+ explicit
+ matrix( T start=T(0), T step=T(0) )
+ {
+ for( int i=0; i!=Rows; ++i )
+ for( int j=0; j!=Cols; ++j,start+=step )
+ a[i][j]=b[i][j]=start;
+ }
+ };
+
+ template <int Rows,int Cols,class Tag1,class T1,class Tag2,class T2>
+ void
+ dump_ab( matrix<Tag1,Rows,Cols,T1> const & a, matrix<Tag2,Rows,Cols,T2> const & b )
+ {
+ detail::dump_ab(a.a,b.a);
+ }
+ }
+
+namespace
+boost
+ {
+ namespace
+ qvm
+ {
+ template <class Tag,int Rows,int Cols,class T>
+ struct
+ mat_traits< test_qvm::matrix<Tag,Rows,Cols,T> >:
+ mat_traits_defaults<test_qvm::matrix<Tag,Rows,Cols,T>,T,Rows,Cols>
+ {
+ typedef mat_traits_defaults<test_qvm::matrix<Tag,Rows,Cols,T>,T,Rows,Cols> base;
+
+ template <int R,int C>
+ static
+ typename base::scalar_type &
+ write_element( typename base::mat_type & m )
+ {
+ BOOST_QVM_STATIC_ASSERT(R>=0);
+ BOOST_QVM_STATIC_ASSERT(R<Rows);
+ BOOST_QVM_STATIC_ASSERT(C>=0);
+ BOOST_QVM_STATIC_ASSERT(C<Cols);
+ return m.a[R][C];
+ }
+
+ using base::write_element_idx;
+ };
+
+ template <class Tag,class T,int R1,int C1,int R2,int C2,int Rows,int Cols>
+ struct
+ deduce_mat2<test_qvm::matrix<Tag,R1,C1,T>,test_qvm::matrix<Tag,R2,C2,T>,Rows,Cols>
+ {
+ typedef test_qvm::matrix<Tag,Rows,Cols,T> type;
+ };
+ }
+ }
+
+namespace
+ {
+ struct M1;
+ struct M2;
+ struct M3;
+ }
+
+#endif
diff --git a/src/boost/libs/qvm/test/test_qvm_quaternion.hpp b/src/boost/libs/qvm/test/test_qvm_quaternion.hpp
new file mode 100644
index 000000000..eab6b8418
--- /dev/null
+++ b/src/boost/libs/qvm/test/test_qvm_quaternion.hpp
@@ -0,0 +1,80 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_QVM_EF9152E42E4711DFB699737156D89593
+#define BOOST_QVM_EF9152E42E4711DFB699737156D89593
+
+#include <boost/qvm/quat_traits_defaults.hpp>
+#include <boost/qvm/deduce_quat.hpp>
+#include <boost/qvm/assert.hpp>
+#include "test_qvm.hpp"
+
+namespace
+test_qvm
+ {
+ template <class Tag,class T=float>
+ struct
+ quaternion
+ {
+ T a[4];
+ mutable T b[4];
+
+ explicit
+ quaternion( T start=T(0), T step=T(0) )
+ {
+ for( int i=0; i!=4; ++i,start+=step )
+ a[i]=b[i]=start;
+ }
+ };
+
+ template <class Tag1,class T1,class Tag2,class T2>
+ void
+ dump_ab( quaternion<Tag1,T1> const & a, quaternion<Tag2,T2> const & b )
+ {
+ detail::dump_ab(a.a,b.a);
+ }
+ }
+
+namespace
+boost
+ {
+ namespace
+ qvm
+ {
+ template <class Tag,class T>
+ struct
+ quat_traits< test_qvm::quaternion<Tag,T> >:
+ quat_traits_defaults<test_qvm::quaternion<Tag,T>,T>
+ {
+ typedef quat_traits_defaults<test_qvm::quaternion<Tag,T>,T> base;
+
+ template <int I>
+ static
+ typename base::scalar_type &
+ write_element( typename base::quat_type & m )
+ {
+ BOOST_QVM_STATIC_ASSERT(I>=0);
+ BOOST_QVM_STATIC_ASSERT(I<4);
+ return m.a[I];
+ }
+ };
+
+ template <class Tag,class T>
+ struct
+ deduce_quat2<test_qvm::quaternion<Tag,T>,test_qvm::quaternion<Tag,T> >
+ {
+ typedef test_qvm::quaternion<Tag,T> type;
+ };
+ }
+ }
+
+namespace
+ {
+ struct Q1;
+ struct Q2;
+ struct Q3;
+ }
+
+#endif
diff --git a/src/boost/libs/qvm/test/test_qvm_vector.hpp b/src/boost/libs/qvm/test/test_qvm_vector.hpp
new file mode 100644
index 000000000..1214e9d42
--- /dev/null
+++ b/src/boost/libs/qvm/test/test_qvm_vector.hpp
@@ -0,0 +1,82 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_QVM_02C176D6B3AB11DE979F9A0D56D89593
+#define BOOST_QVM_02C176D6B3AB11DE979F9A0D56D89593
+
+#include <boost/qvm/vec_traits_defaults.hpp>
+#include <boost/qvm/deduce_vec.hpp>
+#include <boost/qvm/assert.hpp>
+#include "test_qvm.hpp"
+
+namespace
+test_qvm
+ {
+ template <class Tag,int Dim,class T=float>
+ struct
+ vector
+ {
+ T a[Dim];
+ mutable T b[Dim];
+
+ explicit
+ vector( T start=T(0), T step=T(0) )
+ {
+ for( int i=0; i!=Dim; ++i,start+=step )
+ a[i]=b[i]=start;
+ }
+ };
+
+ template <int Dim,class Tag1,class T1,class Tag2,class T2>
+ void
+ dump_ab( vector<Tag1,Dim,T1> const & a, vector<Tag2,Dim,T2> const & b )
+ {
+ detail::dump_ab(a.a,b.a);
+ }
+ }
+
+namespace
+boost
+ {
+ namespace
+ qvm
+ {
+ template <class Tag,int Dim,class T>
+ struct
+ vec_traits< test_qvm::vector<Tag,Dim,T> >:
+ vec_traits_defaults<test_qvm::vector<Tag,Dim,T>,T,Dim>
+ {
+ typedef vec_traits_defaults<test_qvm::vector<Tag,Dim,T>,T,Dim>base;
+
+ template <int I>
+ static
+ typename base::scalar_type &
+ write_element( typename base::vec_type & m )
+ {
+ BOOST_QVM_STATIC_ASSERT(I>=0);
+ BOOST_QVM_STATIC_ASSERT(I<Dim);
+ return m.a[I];
+ }
+
+ using base::write_element_idx;
+ };
+
+ template <class Tag,class T,int D1,int D2,int Dim>
+ struct
+ deduce_vec2<test_qvm::vector<Tag,D1,T>,test_qvm::vector<Tag,D2,T>,Dim>
+ {
+ typedef test_qvm::vector<Tag,Dim,T> type;
+ };
+ }
+ }
+
+namespace
+ {
+ struct V1;
+ struct V2;
+ struct V3;
+ }
+
+#endif
diff --git a/src/boost/libs/qvm/test/to_string_test.cpp b/src/boost/libs/qvm/test/to_string_test.cpp
new file mode 100644
index 000000000..17d8eb863
--- /dev/null
+++ b/src/boost/libs/qvm/test/to_string_test.cpp
@@ -0,0 +1,67 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/to_string.hpp>
+#include <boost/qvm/quat_operations.hpp>
+#include <boost/qvm/vec_operations.hpp>
+#include <boost/qvm/mat_operations.hpp>
+#include "test_qvm_matrix.hpp"
+#include "test_qvm_quaternion.hpp"
+#include "test_qvm_vector.hpp"
+
+namespace
+ {
+ template <int Rows,int Cols>
+ void
+ test_matrix( std::string const & gold )
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::matrix<M1,Rows,Cols,int> const x(42,1);
+ std::string s=to_string(x);
+ BOOST_TEST(s==gold);
+ }
+
+ template <int Dim>
+ void
+ test_vector( std::string const & gold )
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::vector<V1,Dim,int> const x(42,1);
+ std::string s=to_string(x);
+ BOOST_TEST(s==gold);
+ }
+
+ void
+ test_quaternion( std::string const & gold )
+ {
+ using namespace boost::qvm::sfinae;
+ test_qvm::quaternion<Q1,int> const x(42,1);
+ std::string s=to_string(x);
+ BOOST_TEST(s==gold);
+ }
+ }
+
+int
+main()
+ {
+ test_matrix<1,2>("((42,43))");
+ test_matrix<2,1>("((42)(43))");
+ test_matrix<2,2>("((42,43)(44,45))");
+ test_matrix<1,3>("((42,43,44))");
+ test_matrix<3,1>("((42)(43)(44))");
+ test_matrix<3,3>("((42,43,44)(45,46,47)(48,49,50))");
+ test_matrix<1,4>("((42,43,44,45))");
+ test_matrix<4,1>("((42)(43)(44)(45))");
+ test_matrix<4,4>("((42,43,44,45)(46,47,48,49)(50,51,52,53)(54,55,56,57))");
+ test_matrix<1,5>("((42,43,44,45,46))");
+ test_matrix<5,1>("((42)(43)(44)(45)(46))");
+ test_matrix<5,5>("((42,43,44,45,46)(47,48,49,50,51)(52,53,54,55,56)(57,58,59,60,61)(62,63,64,65,66))");
+ test_vector<2>("(42,43)");
+ test_vector<3>("(42,43,44)");
+ test_vector<4>("(42,43,44,45)");
+ test_vector<5>("(42,43,44,45,46)");
+ test_quaternion("(42,43,44,45)");
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/transform_test.cpp b/src/boost/libs/qvm/test/transform_test.cpp
new file mode 100644
index 000000000..6fed948f7
--- /dev/null
+++ b/src/boost/libs/qvm/test/transform_test.cpp
@@ -0,0 +1,43 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/vec_operations.hpp>
+#include <boost/qvm/vec.hpp>
+#include <boost/qvm/vec_mat_operations.hpp>
+#include <boost/qvm/vec_access.hpp>
+#include <boost/qvm/map_mat_mat.hpp>
+#include <boost/qvm/map_mat_vec.hpp>
+#include <boost/qvm/swizzle.hpp>
+#include "test_qvm_matrix.hpp"
+#include "test_qvm_vector.hpp"
+#include "test_qvm.hpp"
+
+namespace
+ {
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ test_qvm::matrix<M1,4,4> m=rot_mat<4>(test_qvm::vector<V1,3>(1,0),1.0f);
+ X(col<3>(m)) = 42;
+ Y(col<3>(m)) = 42;
+ Z(col<3>(m)) = 42;
+ test_qvm::vector<V1,3> v(42,1);
+ test_qvm::vector<V1,3> mv=transform_vector(m,v);
+ test_qvm::vector<V1,3> mp=transform_point(m,v);
+ test_qvm::vector<V1,3> v3=del_row_col<3,3>(m) * v;
+ test_qvm::vector<V1,3> v4=XYZ(m*XYZ1(v));
+ BOOST_QVM_TEST_EQ(mv.a,v3.a);
+ BOOST_QVM_TEST_EQ(mp.a,v4.a);
+ }
+ }
+
+int
+main()
+ {
+ test();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/translation_mat_test.cpp b/src/boost/libs/qvm/test/translation_mat_test.cpp
new file mode 100644
index 000000000..7706f5c16
--- /dev/null
+++ b/src/boost/libs/qvm/test/translation_mat_test.cpp
@@ -0,0 +1,42 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/map.hpp>
+#include <boost/qvm/mat_traits_array.hpp>
+#include <boost/qvm/vec_operations.hpp>
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/mat.hpp>
+#include "test_qvm_vector.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Dim>
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ test_qvm::vector<V1,Dim-1> x(42,1);
+ float r1[Dim][Dim];
+ test_qvm::translation(r1,x.a);
+ float r2[Dim][Dim];
+ assign(r2,translation_mat(x));
+ BOOST_QVM_TEST_EQ(r1,r2);
+ test_qvm::scalar_multiply_v(x.b,x.a,2.0f);
+ col<Dim-1>(del_row<Dim-1>(translation_mat(x))) *= 2;
+ BOOST_QVM_TEST_EQ(x.a,x.b);
+ translation_mat(x) + translation_mat(x);
+ -translation_mat(x);
+ }
+ }
+
+int
+main()
+ {
+ test<3>();
+ test<4>();
+ test<5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/translation_test.cpp b/src/boost/libs/qvm/test/translation_test.cpp
new file mode 100644
index 000000000..be4d3c81c
--- /dev/null
+++ b/src/boost/libs/qvm/test/translation_test.cpp
@@ -0,0 +1,41 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_operations.hpp>
+#include <boost/qvm/vec.hpp>
+#include <boost/qvm/map_mat_vec.hpp>
+#include "test_qvm_matrix.hpp"
+#include "test_qvm_vector.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int D>
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ test_qvm::matrix<M1,D,D> x(42,1);
+ test_qvm::vector<V1,D-1> y=translation(x);
+ for( int i=0; i!=D-1; ++i )
+ y.b[i]=x.a[i][D-1];
+ BOOST_QVM_TEST_EQ(y.a,y.b);
+ translation(x) *= 2;
+ for( int i=0; i!=D-1; ++i )
+ x.b[i][D-1] *= 2;
+ BOOST_QVM_TEST_EQ(x.a,x.b);
+ translation(x) + translation(x);
+ -translation(x);
+ }
+ }
+
+int
+main()
+ {
+ test<3>();
+ test<4>();
+ test<5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/transpose_test.cpp b/src/boost/libs/qvm/test/transpose_test.cpp
new file mode 100644
index 000000000..3fffa36f9
--- /dev/null
+++ b/src/boost/libs/qvm/test/transpose_test.cpp
@@ -0,0 +1,52 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/map_mat_mat.hpp>
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/mat_traits_array.hpp>
+#include <boost/qvm/mat.hpp>
+#include "test_qvm_matrix.hpp"
+#include "gold.hpp"
+
+namespace
+ {
+ template <int Rows,int Cols>
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ test_qvm::matrix<M1,Rows,Cols> x(42,1);
+ float r1[Cols][Rows];
+ for( int i=0; i!=Rows; ++i )
+ for( int j=0; j!=Cols; ++j )
+ r1[j][i]=x.a[i][j];
+ float r2[Cols][Rows];
+ assign(r2,transposed(x));
+ BOOST_QVM_TEST_EQ(r1,r2);
+ test_qvm::scalar_multiply_m(x.b,x.a,2.0f);
+ transposed(x) *= 2;
+ BOOST_QVM_TEST_EQ(x.a,x.b);
+ transposed(x) + transposed(x);
+ -transposed(x);
+ }
+ }
+
+int
+main()
+ {
+ test<1,2>();
+ test<2,1>();
+ test<2,2>();
+ test<1,3>();
+ test<3,1>();
+ test<3,3>();
+ test<1,4>();
+ test<4,1>();
+ test<4,4>();
+ test<1,5>();
+ test<5,1>();
+ test<5,5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/vec_index_test.cpp b/src/boost/libs/qvm/test/vec_index_test.cpp
new file mode 100644
index 000000000..88f587acb
--- /dev/null
+++ b/src/boost/libs/qvm/test/vec_index_test.cpp
@@ -0,0 +1,28 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include "test_qvm_vector.hpp"
+
+int
+main()
+ {
+ using namespace boost::qvm;
+
+ typedef test_qvm::vector<V1,4> V;
+ V v;
+ v.a[0]=42.0f;
+ v.a[1]=43.0f;
+ v.a[2]=44.0f;
+ v.a[3]=45.0f;
+ BOOST_TEST(vec_traits<V>::read_element_idx(0,v)==v.a[0]);
+ BOOST_TEST(vec_traits<V>::read_element_idx(1,v)==v.a[1]);
+ BOOST_TEST(vec_traits<V>::read_element_idx(2,v)==v.a[2]);
+ BOOST_TEST(vec_traits<V>::read_element_idx(3,v)==v.a[3]);
+ BOOST_TEST(&vec_traits<V>::write_element_idx(0,v)==&v.a[0]);
+ BOOST_TEST(&vec_traits<V>::write_element_idx(1,v)==&v.a[1]);
+ BOOST_TEST(&vec_traits<V>::write_element_idx(2,v)==&v.a[2]);
+ BOOST_TEST(&vec_traits<V>::write_element_idx(3,v)==&v.a[3]);
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/vec_register_test.cpp b/src/boost/libs/qvm/test/vec_register_test.cpp
new file mode 100644
index 000000000..84a911133
--- /dev/null
+++ b/src/boost/libs/qvm/test/vec_register_test.cpp
@@ -0,0 +1,225 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+//Copyright (c) 2018 agate-pris
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/core/lightweight_test.hpp>
+#include <boost/qvm/vec_register.hpp>
+
+struct v2
+{
+ float x;
+ float y;
+};
+
+struct v3 : v2
+{
+ float z;
+};
+
+struct v4 : v3
+{
+ float w;
+};
+
+struct v2r
+{
+ float xr;
+ float yr;
+};
+
+struct v3r : v2r
+{
+ float zr;
+};
+
+struct v4r : v3r
+{
+ float wr;
+};
+
+struct v2rw : v2, v2r { };
+struct v3rw : v3, v3r { };
+struct v4rw : v4, v4r { };
+
+BOOST_QVM_REGISTER_VEC_2(v2, float, x, y)
+BOOST_QVM_REGISTER_VEC_3(v3, float, x, y, z)
+BOOST_QVM_REGISTER_VEC_4(v4, float, x, y, z, w)
+
+BOOST_QVM_REGISTER_VEC_2_READ(v2r, float, xr, yr)
+BOOST_QVM_REGISTER_VEC_3_READ(v3r, float, xr, yr, zr)
+BOOST_QVM_REGISTER_VEC_4_READ(v4r, float, xr, yr, zr, wr)
+
+BOOST_QVM_REGISTER_VEC_2_READ_WRITE(v2rw, float, xr, yr, x, y)
+BOOST_QVM_REGISTER_VEC_3_READ_WRITE(v3rw, float, xr, yr, zr, x, y, z)
+BOOST_QVM_REGISTER_VEC_4_READ_WRITE(v4rw, float, xr, yr, zr, wr, x, y, z, w)
+
+int main()
+{
+ using namespace boost::qvm;
+
+ v2 v_v2;
+ v3 v_v3;
+ v4 v_v4;
+ v2r v_v2r;
+ v3r v_v3r;
+ v4r v_v4r;
+ v2rw v_v2rw;
+ v3rw v_v3rw;
+ v4rw v_v4rw;
+
+ v_v2.x = 41.f;
+ v_v3.x = 42.f;
+ v_v4.x = 43.f;
+ v_v2.y = 44.f;
+ v_v3.y = 45.f;
+ v_v4.y = 46.f;
+ v_v3.z = 47.f;
+ v_v4.z = 48.f;
+ v_v4.w = 49.f;
+
+ v_v2r.xr = 51.f;
+ v_v3r.xr = 52.f;
+ v_v4r.xr = 53.f;
+ v_v2r.yr = 54.f;
+ v_v3r.yr = 55.f;
+ v_v4r.yr = 56.f;
+ v_v3r.zr = 57.f;
+ v_v4r.zr = 58.f;
+ v_v4r.wr = 59.f;
+
+ v_v2rw.x = 61.f;
+ v_v3rw.x = 62.f;
+ v_v4rw.x = 63.f;
+ v_v2rw.y = 64.f;
+ v_v3rw.y = 65.f;
+ v_v4rw.y = 66.f;
+ v_v3rw.z = 67.f;
+ v_v4rw.z = 68.f;
+ v_v4rw.w = 69.f;
+
+ v_v2rw.xr = 71.f;
+ v_v3rw.xr = 72.f;
+ v_v4rw.xr = 73.f;
+ v_v2rw.yr = 74.f;
+ v_v3rw.yr = 75.f;
+ v_v4rw.yr = 76.f;
+ v_v3rw.zr = 77.f;
+ v_v4rw.zr = 78.f;
+ v_v4rw.wr = 79.f;
+
+ BOOST_TEST(vec_traits<v2 >::read_element<0>(v_v2 ) == v_v2 .x );
+ BOOST_TEST(vec_traits<v3 >::read_element<0>(v_v3 ) == v_v3 .x );
+ BOOST_TEST(vec_traits<v4 >::read_element<0>(v_v4 ) == v_v4 .x );
+ BOOST_TEST(vec_traits<v2r >::read_element<0>(v_v2r ) == v_v2r .xr);
+ BOOST_TEST(vec_traits<v3r >::read_element<0>(v_v3r ) == v_v3r .xr);
+ BOOST_TEST(vec_traits<v4r >::read_element<0>(v_v4r ) == v_v4r .xr);
+ BOOST_TEST(vec_traits<v2rw>::read_element<0>(v_v2rw) == v_v2rw.xr);
+ BOOST_TEST(vec_traits<v3rw>::read_element<0>(v_v3rw) == v_v3rw.xr);
+ BOOST_TEST(vec_traits<v4rw>::read_element<0>(v_v4rw) == v_v4rw.xr);
+ BOOST_TEST(vec_traits<v2 >::read_element<1>(v_v2 ) == v_v2 .y );
+ BOOST_TEST(vec_traits<v3 >::read_element<1>(v_v3 ) == v_v3 .y );
+ BOOST_TEST(vec_traits<v4 >::read_element<1>(v_v4 ) == v_v4 .y );
+ BOOST_TEST(vec_traits<v2r >::read_element<1>(v_v2r ) == v_v2r .yr);
+ BOOST_TEST(vec_traits<v3r >::read_element<1>(v_v3r ) == v_v3r .yr);
+ BOOST_TEST(vec_traits<v4r >::read_element<1>(v_v4r ) == v_v4r .yr);
+ BOOST_TEST(vec_traits<v2rw>::read_element<1>(v_v2rw) == v_v2rw.yr);
+ BOOST_TEST(vec_traits<v3rw>::read_element<1>(v_v3rw) == v_v3rw.yr);
+ BOOST_TEST(vec_traits<v4rw>::read_element<1>(v_v4rw) == v_v4rw.yr);
+ BOOST_TEST(vec_traits<v3 >::read_element<2>(v_v3 ) == v_v3 .z );
+ BOOST_TEST(vec_traits<v4 >::read_element<2>(v_v4 ) == v_v4 .z );
+ BOOST_TEST(vec_traits<v3r >::read_element<2>(v_v3r ) == v_v3r .zr);
+ BOOST_TEST(vec_traits<v4r >::read_element<2>(v_v4r ) == v_v4r .zr);
+ BOOST_TEST(vec_traits<v3rw>::read_element<2>(v_v3rw) == v_v3rw.zr);
+ BOOST_TEST(vec_traits<v4rw>::read_element<2>(v_v4rw) == v_v4rw.zr);
+ BOOST_TEST(vec_traits<v4 >::read_element<3>(v_v4 ) == v_v4 .w );
+ BOOST_TEST(vec_traits<v4r >::read_element<3>(v_v4r ) == v_v4r .wr);
+ BOOST_TEST(vec_traits<v4rw>::read_element<3>(v_v4rw) == v_v4rw.wr);
+
+ BOOST_TEST(vec_traits<v2 >::read_element_idx(0, v_v2 ) == v_v2 .x );
+ BOOST_TEST(vec_traits<v3 >::read_element_idx(0, v_v3 ) == v_v3 .x );
+ BOOST_TEST(vec_traits<v4 >::read_element_idx(0, v_v4 ) == v_v4 .x );
+ BOOST_TEST(vec_traits<v2r >::read_element_idx(0, v_v2r ) == v_v2r .xr);
+ BOOST_TEST(vec_traits<v3r >::read_element_idx(0, v_v3r ) == v_v3r .xr);
+ BOOST_TEST(vec_traits<v4r >::read_element_idx(0, v_v4r ) == v_v4r .xr);
+ BOOST_TEST(vec_traits<v2rw>::read_element_idx(0, v_v2rw) == v_v2rw.xr);
+ BOOST_TEST(vec_traits<v3rw>::read_element_idx(0, v_v3rw) == v_v3rw.xr);
+ BOOST_TEST(vec_traits<v4rw>::read_element_idx(0, v_v4rw) == v_v4rw.xr);
+ BOOST_TEST(vec_traits<v2 >::read_element_idx(1, v_v2 ) == v_v2 .y );
+ BOOST_TEST(vec_traits<v3 >::read_element_idx(1, v_v3 ) == v_v3 .y );
+ BOOST_TEST(vec_traits<v4 >::read_element_idx(1, v_v4 ) == v_v4 .y );
+ BOOST_TEST(vec_traits<v2r >::read_element_idx(1, v_v2r ) == v_v2r .yr);
+ BOOST_TEST(vec_traits<v3r >::read_element_idx(1, v_v3r ) == v_v3r .yr);
+ BOOST_TEST(vec_traits<v4r >::read_element_idx(1, v_v4r ) == v_v4r .yr);
+ BOOST_TEST(vec_traits<v2rw>::read_element_idx(1, v_v2rw) == v_v2rw.yr);
+ BOOST_TEST(vec_traits<v3rw>::read_element_idx(1, v_v3rw) == v_v3rw.yr);
+ BOOST_TEST(vec_traits<v4rw>::read_element_idx(1, v_v4rw) == v_v4rw.yr);
+ BOOST_TEST(vec_traits<v3 >::read_element_idx(2, v_v3 ) == v_v3 .z );
+ BOOST_TEST(vec_traits<v4 >::read_element_idx(2, v_v4 ) == v_v4 .z );
+ BOOST_TEST(vec_traits<v3r >::read_element_idx(2, v_v3r ) == v_v3r .zr);
+ BOOST_TEST(vec_traits<v4r >::read_element_idx(2, v_v4r ) == v_v4r .zr);
+ BOOST_TEST(vec_traits<v3rw>::read_element_idx(2, v_v3rw) == v_v3rw.zr);
+ BOOST_TEST(vec_traits<v4rw>::read_element_idx(2, v_v4rw) == v_v4rw.zr);
+ BOOST_TEST(vec_traits<v4 >::read_element_idx(3, v_v4 ) == v_v4 .w );
+ BOOST_TEST(vec_traits<v4r >::read_element_idx(3, v_v4r ) == v_v4r .wr);
+ BOOST_TEST(vec_traits<v4rw>::read_element_idx(3, v_v4rw) == v_v4rw.wr);
+
+ BOOST_TEST(&vec_traits<v2 >::write_element<0>(v_v2 ) == &v_v2 .x );
+ BOOST_TEST(&vec_traits<v3 >::write_element<0>(v_v3 ) == &v_v3 .x );
+ BOOST_TEST(&vec_traits<v4 >::write_element<0>(v_v4 ) == &v_v4 .x );
+ BOOST_TEST_NOT(&vec_traits<v2rw>::write_element<0>(v_v2rw) == &v_v2rw.xr);
+ BOOST_TEST_NOT(&vec_traits<v3rw>::write_element<0>(v_v3rw) == &v_v3rw.xr);
+ BOOST_TEST_NOT(&vec_traits<v4rw>::write_element<0>(v_v4rw) == &v_v4rw.xr);
+ BOOST_TEST(&vec_traits<v2rw>::write_element<0>(v_v2rw) == &v_v2rw.x );
+ BOOST_TEST(&vec_traits<v3rw>::write_element<0>(v_v3rw) == &v_v3rw.x );
+ BOOST_TEST(&vec_traits<v4rw>::write_element<0>(v_v4rw) == &v_v4rw.x );
+ BOOST_TEST(&vec_traits<v2 >::write_element<1>(v_v2 ) == &v_v2 .y );
+ BOOST_TEST(&vec_traits<v3 >::write_element<1>(v_v3 ) == &v_v3 .y );
+ BOOST_TEST(&vec_traits<v4 >::write_element<1>(v_v4 ) == &v_v4 .y );
+ BOOST_TEST_NOT(&vec_traits<v2rw>::write_element<1>(v_v2rw) == &v_v2rw.yr);
+ BOOST_TEST_NOT(&vec_traits<v3rw>::write_element<1>(v_v3rw) == &v_v3rw.yr);
+ BOOST_TEST_NOT(&vec_traits<v4rw>::write_element<1>(v_v4rw) == &v_v4rw.yr);
+ BOOST_TEST(&vec_traits<v2rw>::write_element<1>(v_v2rw) == &v_v2rw.y );
+ BOOST_TEST(&vec_traits<v3rw>::write_element<1>(v_v3rw) == &v_v3rw.y );
+ BOOST_TEST(&vec_traits<v4rw>::write_element<1>(v_v4rw) == &v_v4rw.y );
+ BOOST_TEST(&vec_traits<v3 >::write_element<2>(v_v3 ) == &v_v3 .z );
+ BOOST_TEST(&vec_traits<v4 >::write_element<2>(v_v4 ) == &v_v4 .z );
+ BOOST_TEST_NOT(&vec_traits<v3rw>::write_element<2>(v_v3rw) == &v_v3rw.zr);
+ BOOST_TEST_NOT(&vec_traits<v4rw>::write_element<2>(v_v4rw) == &v_v4rw.zr);
+ BOOST_TEST(&vec_traits<v3rw>::write_element<2>(v_v3rw) == &v_v3rw.z );
+ BOOST_TEST(&vec_traits<v4rw>::write_element<2>(v_v4rw) == &v_v4rw.z );
+ BOOST_TEST(&vec_traits<v4 >::write_element<3>(v_v4 ) == &v_v4 .w );
+ BOOST_TEST_NOT(&vec_traits<v4rw>::write_element<3>(v_v4rw) == &v_v4rw.wr);
+ BOOST_TEST(&vec_traits<v4rw>::write_element<3>(v_v4rw) == &v_v4rw.w );
+
+ BOOST_TEST(&vec_traits<v2 >::write_element_idx(0, v_v2 ) == &v_v2 .x );
+ BOOST_TEST(&vec_traits<v3 >::write_element_idx(0, v_v3 ) == &v_v3 .x );
+ BOOST_TEST(&vec_traits<v4 >::write_element_idx(0, v_v4 ) == &v_v4 .x );
+ BOOST_TEST_NOT(&vec_traits<v2rw>::write_element_idx(0, v_v2rw) == &v_v2rw.xr);
+ BOOST_TEST_NOT(&vec_traits<v3rw>::write_element_idx(0, v_v3rw) == &v_v3rw.xr);
+ BOOST_TEST_NOT(&vec_traits<v4rw>::write_element_idx(0, v_v4rw) == &v_v4rw.xr);
+ BOOST_TEST(&vec_traits<v2rw>::write_element_idx(0, v_v2rw) == &v_v2rw.x );
+ BOOST_TEST(&vec_traits<v3rw>::write_element_idx(0, v_v3rw) == &v_v3rw.x );
+ BOOST_TEST(&vec_traits<v4rw>::write_element_idx(0, v_v4rw) == &v_v4rw.x );
+ BOOST_TEST(&vec_traits<v2 >::write_element_idx(1, v_v2 ) == &v_v2 .y );
+ BOOST_TEST(&vec_traits<v3 >::write_element_idx(1, v_v3 ) == &v_v3 .y );
+ BOOST_TEST(&vec_traits<v4 >::write_element_idx(1, v_v4 ) == &v_v4 .y );
+ BOOST_TEST_NOT(&vec_traits<v2rw>::write_element_idx(1, v_v2rw) == &v_v2rw.yr);
+ BOOST_TEST_NOT(&vec_traits<v3rw>::write_element_idx(1, v_v3rw) == &v_v3rw.yr);
+ BOOST_TEST_NOT(&vec_traits<v4rw>::write_element_idx(1, v_v4rw) == &v_v4rw.yr);
+ BOOST_TEST(&vec_traits<v2rw>::write_element_idx(1, v_v2rw) == &v_v2rw.y );
+ BOOST_TEST(&vec_traits<v3rw>::write_element_idx(1, v_v3rw) == &v_v3rw.y );
+ BOOST_TEST(&vec_traits<v4rw>::write_element_idx(1, v_v4rw) == &v_v4rw.y );
+ BOOST_TEST(&vec_traits<v3 >::write_element_idx(2, v_v3 ) == &v_v3 .z );
+ BOOST_TEST(&vec_traits<v4 >::write_element_idx(2, v_v4 ) == &v_v4 .z );
+ BOOST_TEST_NOT(&vec_traits<v3rw>::write_element_idx(2, v_v3rw) == &v_v3rw.zr);
+ BOOST_TEST_NOT(&vec_traits<v4rw>::write_element_idx(2, v_v4rw) == &v_v4rw.zr);
+ BOOST_TEST(&vec_traits<v3rw>::write_element_idx(2, v_v3rw) == &v_v3rw.z );
+ BOOST_TEST(&vec_traits<v4rw>::write_element_idx(2, v_v4rw) == &v_v4rw.z );
+ BOOST_TEST(&vec_traits<v4 >::write_element_idx(3, v_v4 ) == &v_v4 .w );
+ BOOST_TEST_NOT(&vec_traits<v4rw>::write_element_idx(3, v_v4rw) == &v_v4rw.wr);
+ BOOST_TEST(&vec_traits<v4rw>::write_element_idx(3, v_v4rw) == &v_v4rw.w );
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/qvm/test/vec_traits_array_test.cpp b/src/boost/libs/qvm/test/vec_traits_array_test.cpp
new file mode 100644
index 000000000..f5b61c852
--- /dev/null
+++ b/src/boost/libs/qvm/test/vec_traits_array_test.cpp
@@ -0,0 +1,83 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_traits_array.hpp>
+#include <boost/qvm/vec_operations.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+template <class T,class U>
+struct same_type;
+
+template <class T>
+struct
+same_type<T,T>
+ {
+ };
+
+template <class T,class P>
+void
+test_ref_cast( T & v, P * ptr )
+ {
+ using namespace boost::qvm;
+ BOOST_QVM_STATIC_ASSERT(is_vec<T>::value);
+ BOOST_QVM_STATIC_ASSERT(vec_traits<T>::dim==3);
+ BOOST_TEST(vec_traits<T>::template read_element<0>(v)==ptr[0]);
+ BOOST_TEST(vec_traits<T>::template read_element<1>(v)==ptr[1]);
+ BOOST_TEST(vec_traits<T>::template read_element<2>(v)==ptr[2]);
+ BOOST_TEST(&vec_traits<T>::template write_element<0>(v)==&ptr[0]);
+ BOOST_TEST(&vec_traits<T>::template write_element<1>(v)==&ptr[1]);
+ BOOST_TEST(&vec_traits<T>::template write_element<2>(v)==&ptr[2]);
+ BOOST_TEST(&v[0]==&ptr[0]);
+ BOOST_TEST(&v[1]==&ptr[1]);
+ BOOST_TEST(&v[2]==&ptr[2]);
+ }
+
+int
+main()
+ {
+ using namespace boost::qvm;
+ {
+ BOOST_QVM_STATIC_ASSERT(is_vec<int[3]>::value);
+ BOOST_QVM_STATIC_ASSERT(!is_vec<int[3][3]>::value);
+ BOOST_QVM_STATIC_ASSERT(!is_vec<int[3][3][3]>::value);
+ BOOST_QVM_STATIC_ASSERT((vec_traits<int[3]>::dim==3));
+ same_type<vec_traits<int[3]>::scalar_type,int>();
+ same_type< vec<int,3>, deduce_vec<int[3]>::type >();
+ same_type< vec<int,3>, deduce_vec<int const[3]>::type >();
+ int arr[3] = {0,1,2};
+ BOOST_TEST((vec_traits<int[3]>::read_element<0>(arr)==0));
+ BOOST_TEST((vec_traits<int[3]>::read_element<1>(arr)==1));
+ BOOST_TEST((vec_traits<int[3]>::read_element<2>(arr)==2));
+ BOOST_TEST((vec_traits<int const[3]>::read_element<0>(arr)==0));
+ BOOST_TEST((vec_traits<int const[3]>::read_element<1>(arr)==1));
+ BOOST_TEST((vec_traits<int const[3]>::read_element<2>(arr)==2));
+ BOOST_TEST((vec_traits<int[3]>::read_element_idx(0,arr)==0));
+ BOOST_TEST((vec_traits<int[3]>::read_element_idx(1,arr)==1));
+ BOOST_TEST((vec_traits<int[3]>::read_element_idx(2,arr)==2));
+ BOOST_TEST((vec_traits<int const[3]>::read_element_idx(0,arr)==0));
+ BOOST_TEST((vec_traits<int const[3]>::read_element_idx(1,arr)==1));
+ BOOST_TEST((vec_traits<int const[3]>::read_element_idx(2,arr)==2));
+ BOOST_TEST((&vec_traits<int[3]>::write_element<0>(arr)==&arr[0]));
+ BOOST_TEST((&vec_traits<int[3]>::write_element<1>(arr)==&arr[1]));
+ BOOST_TEST((&vec_traits<int[3]>::write_element<2>(arr)==&arr[2]));
+ BOOST_TEST((&vec_traits<int[3]>::write_element_idx(0,arr)==&arr[0]));
+ BOOST_TEST((&vec_traits<int[3]>::write_element_idx(1,arr)==&arr[1]));
+ BOOST_TEST((&vec_traits<int[3]>::write_element_idx(2,arr)==&arr[2]));
+ }
+ {
+ int arr[42] = {0};
+ int * ptr=arr+5;
+ ptr[0]=42;
+ ptr[1]=43;
+ ptr[2]=44;
+ test_ref_cast(ptr_vref<3>(ptr),ptr);
+ int v[3] = {1,1,1};
+ ptr_vref<3>(ptr) += vref(v);
+ BOOST_TEST(ptr[0]==43);
+ BOOST_TEST(ptr[1]==44);
+ BOOST_TEST(ptr[2]==45);
+ }
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/zero_mat_test.cpp b/src/boost/libs/qvm/test/zero_mat_test.cpp
new file mode 100644
index 000000000..363899dbc
--- /dev/null
+++ b/src/boost/libs/qvm/test/zero_mat_test.cpp
@@ -0,0 +1,78 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/mat_operations.hpp>
+#include <boost/qvm/mat.hpp>
+#include "test_qvm_matrix.hpp"
+
+namespace
+ {
+ template <class T,class U>
+ struct same_type;
+
+ template <class T>
+ struct
+ same_type<T,T>
+ {
+ };
+
+ template <class T,class U>
+ void
+ check_deduction( T const &, U const & )
+ {
+ same_type<T,typename boost::qvm::deduce_mat<U>::type>();
+ }
+
+ template <int Rows,int Cols>
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ test_qvm::matrix<M1,Rows,Cols> m1=zero_mat<float,Rows,Cols>();
+ for( int i=0; i!=Rows; ++i )
+ for( int j=0; j!=Cols; ++j )
+ BOOST_TEST(!m1.a[i][j]);
+ test_qvm::matrix<M2,Rows,Cols> m2(42,1);
+ set_zero(m2);
+ for( int i=0; i!=Rows; ++i )
+ for( int j=0; j!=Cols; ++j )
+ BOOST_TEST(!m2.a[i][j]);
+ check_deduction(mat<float,Rows,Cols>(),zero_mat<float,Rows,Cols>());
+ check_deduction(mat<int,Rows,Cols>(),zero_mat<int,Rows,Cols>());
+ }
+
+ template <int Dim>
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ test_qvm::matrix<M1,Dim,Dim> m1=zero_mat<float,Dim>();
+ for( int i=0; i!=Dim; ++i )
+ for( int j=0; j!=Dim; ++j )
+ BOOST_TEST(!m1.a[i][j]);
+ }
+ }
+
+int
+main()
+ {
+ test<1,2>();
+ test<2,1>();
+ test<2,2>();
+ test<1,3>();
+ test<3,1>();
+ test<3,3>();
+ test<1,4>();
+ test<4,1>();
+ test<4,4>();
+ test<1,5>();
+ test<5,1>();
+ test<5,5>();
+ test<2>();
+ test<3>();
+ test<4>();
+ test<5>();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/zero_quat_test.cpp b/src/boost/libs/qvm/test/zero_quat_test.cpp
new file mode 100644
index 000000000..4ee8b67b7
--- /dev/null
+++ b/src/boost/libs/qvm/test/zero_quat_test.cpp
@@ -0,0 +1,30 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/quat_operations.hpp>
+#include "test_qvm_quaternion.hpp"
+
+namespace
+ {
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ test_qvm::quaternion<Q1> v1=zero_quat<float>();
+ for( int i=0; i!=4; ++i )
+ BOOST_TEST(!v1.a[i]);
+ test_qvm::quaternion<Q2> v2(42,1);
+ set_zero(v2);
+ for( int i=0; i!=4; ++i )
+ BOOST_TEST(!v2.a[i]);
+ }
+ }
+
+int
+main()
+ {
+ test();
+ return boost::report_errors();
+ }
diff --git a/src/boost/libs/qvm/test/zero_vec_test.cpp b/src/boost/libs/qvm/test/zero_vec_test.cpp
new file mode 100644
index 000000000..d742c9aa0
--- /dev/null
+++ b/src/boost/libs/qvm/test/zero_vec_test.cpp
@@ -0,0 +1,53 @@
+//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/qvm/vec_operations.hpp>
+#include <boost/qvm/vec.hpp>
+#include "test_qvm_vector.hpp"
+
+namespace
+ {
+ template <class T,class U>
+ struct same_type;
+
+ template <class T>
+ struct
+ same_type<T,T>
+ {
+ };
+
+ template <class T,class U>
+ void
+ check_deduction( T const &, U const & )
+ {
+ same_type<T,typename boost::qvm::deduce_vec<U>::type>();
+ }
+
+ template <int Dim>
+ void
+ test()
+ {
+ using namespace boost::qvm;
+ test_qvm::vector<V1,Dim> v1=zero_vec<float,Dim>();
+ for( int i=0; i!=Dim; ++i )
+ BOOST_TEST(!v1.a[i]);
+ test_qvm::vector<V2,Dim> v2(42,1);
+ set_zero(v2);
+ for( int i=0; i!=Dim; ++i )
+ BOOST_TEST(!v2.a[i]);
+ check_deduction(vec<float,Dim>(),zero_vec<float,Dim>());
+ check_deduction(vec<int,Dim>(),zero_vec<int,Dim>());
+ }
+ }
+
+int
+main()
+ {
+ test<2>();
+ test<3>();
+ test<4>();
+ test<5>();
+ return boost::report_errors();
+ }