1 //Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
2 
3 //Distributed under the Boost Software License, Version 1.0. (See accompanying
4 //file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 #ifndef BOOST_QVM_C5DC682E196211E0A4C1686BDFD72085
7 #define BOOST_QVM_C5DC682E196211E0A4C1686BDFD72085
8 
9 #include <boost/qvm/deduce_scalar.hpp>
10 #include <boost/qvm/mat_traits.hpp>
11 #include <boost/qvm/static_assert.hpp>
12 
13 namespace
14 boost
15     {
16     namespace
17     qvm
18         {
19         template <class T,int Rows,int Cols>
20         struct mat;
21 
22         namespace
23         qvm_detail
24             {
25             template <class M,int R,int C,
26                 int MR=mat_traits<M>::rows,
27                 int MC=mat_traits<M>::cols>
28             struct
29             deduce_mat_default
30                 {
31                 BOOST_QVM_STATIC_ASSERT(is_mat<M>::value);
32                 typedef mat<typename mat_traits<M>::scalar_type,R,C> type;
33                 };
34 
35             template <class M,int R,int C>
36             struct
37             deduce_mat_default<M,R,C,R,C>
38                 {
39                 BOOST_QVM_STATIC_ASSERT(is_mat<M>::value);
40                 typedef M type;
41                 };
42             }
43 
44         template <class Type,int Rows=mat_traits<Type>::rows,int Cols=mat_traits<Type>::cols>
45         struct
46         deduce_mat
47             {
48             BOOST_QVM_STATIC_ASSERT(is_mat<Type>::value);
49             typedef typename qvm_detail::deduce_mat_default<Type,Rows,Cols>::type type;
50             };
51 
52         namespace
53         qvm_detail
54             {
55             template <class A,class B,int R,int C,
56                 bool VA=is_mat<A>::value,
57                 bool VB=is_mat<B>::value,
58                 int AR=mat_traits<A>::rows,
59                 int AC=mat_traits<A>::cols,
60                 int BR=mat_traits<B>::rows,
61                 int BC=mat_traits<B>::cols>
62             struct
63             deduce_m2_default
64                 {
65                 typedef mat<
66                     typename deduce_scalar<
67                         typename scalar<A>::type,
68                         typename scalar<B>::type>::type,
69                     R,C> type;
70                 };
71 
72             template <class M,int R,int C>
73             struct
74             deduce_m2_default<M,M,R,C,true,true,R,C,R,C>
75                 {
76                 typedef M type;
77                 };
78             }
79 
80         template <class A,class B,int R,int C>
81         struct
82         deduce_mat2
83             {
84             BOOST_QVM_STATIC_ASSERT(is_mat<A>::value || is_mat<B>::value);
85             typedef typename qvm_detail::deduce_m2_default<A,B,R,C>::type type;
86             };
87         }
88     }
89 
90 #endif
91