1910 lines
65 KiB
C++
1910 lines
65 KiB
C++
//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[] ):
|
|
argc(argc),
|
|
argv(argv)
|
|
{
|
|
}
|
|
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;
|
|
}
|