]> Dogcows Code - chaz/yoink/blob - src/cml/et/scalar_promotions.h
now using cml for vectors and math stuff
[chaz/yoink] / src / cml / et / scalar_promotions.h
1 /* -*- C++ -*- ------------------------------------------------------------
2
3 Copyright (c) 2007 Jesse Anders and Demian Nave http://cmldev.net/
4
5 The Configurable Math Library (CML) is distributed under the terms of the
6 Boost Software License, v1.0 (see cml/LICENSE for details).
7
8 *-----------------------------------------------------------------------*/
9 /** @file
10 * @brief
11 */
12
13 #ifndef scalar_promotions_h
14 #define scalar_promotions_h
15
16 #include <cml/core/cml_meta.h>
17
18 namespace cml {
19 namespace et {
20
21 namespace detail {
22
23 /** @class IntPromote
24 * @brief Helper template to int-promote a type.
25 */
26 template<class T> struct IntPromote
27 {
28 /* Signed -> signed int, unsigned -> unsigned int: */
29 typedef typename select_switch<T,
30 unsigned char, unsigned int,
31 unsigned short, unsigned int,
32 signed char, int,
33 char, int,
34 short, int,
35 T, T
36 >::result result;
37 };
38
39 } // namespace detail
40
41 /** @class ScalarPromote
42 * @brief Template for compile-time type promotion via C promotion rules.
43 */
44 template<class E1_in, class E2_in> struct ScalarPromote
45 {
46
47 /* Integral-promote the types (if possible). */
48 typedef typename detail::IntPromote<E1_in>::result E1;
49 typedef typename detail::IntPromote<E2_in>::result E2;
50
51 /* If sizeof(long) == sizeof(unsigned int), promote to unsigned long.
52 * Otherwise, sizeof(long) > sizeof(int), so promote to long.
53 */
54 typedef typename select_if<sizeof(long) == sizeof(unsigned int),
55 unsigned long,
56 long
57 >::result uint_promotion;
58
59 /* Do the selection on the promoted types: */
60 typedef typename select_switch<
61 type_pair<E1,E2>,
62
63 #if defined(CML_USE_LONG_DOUBLE)
64 type_pair<long double,long double>, long double,
65 type_pair<long double,E2>, long double,
66 type_pair<E1,long double>, long double,
67 #endif
68
69 type_pair<double,double>, double,
70 type_pair<double,E2>, double,
71 type_pair<E1,double>, double,
72
73 type_pair<float,float>, float,
74 type_pair<float,E2>, float,
75 type_pair<E1,float>, float,
76
77 type_pair<E1,E2>, void
78
79 >::result float_filter;
80
81 /* The promoted integral types really matter here: */
82 typedef typename select_switch<
83 type_pair<E1,E2>,
84
85 type_pair<unsigned long,unsigned long>, unsigned long,
86 type_pair<unsigned long,E2>, unsigned long,
87 type_pair<E1,unsigned long>, unsigned long,
88
89 type_pair<long,long>, long,
90 type_pair<long,unsigned int>, uint_promotion,
91 type_pair<unsigned int,long>, uint_promotion,
92
93 type_pair<long,E2>, long,
94 type_pair<E1,long>, long,
95
96 type_pair<unsigned int,unsigned int>, unsigned int,
97 type_pair<unsigned int,E2>, unsigned int,
98 type_pair<E1,unsigned int>, unsigned int,
99
100 type_pair<int,int>, int,
101 type_pair<int,E2>, int,
102 type_pair<E1,int>, int,
103
104 type_pair<E1,E2>, void
105
106 >::result int_filter;
107
108 /* Deduce the final type: */
109 typedef typename select_if<
110 same_type<float_filter,void>::is_true,
111 int_filter, float_filter>::result type;
112 };
113
114 } // namespace et
115 } // namespace cml
116
117 #endif
118
119 // -------------------------------------------------------------------------
120 // vim:ft=cpp
This page took 0.034068 seconds and 4 git commands to generate.