File: Upcast.h

package info (click to toggle)
spring 103.0%2Bdfsg2-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 43,720 kB
  • ctags: 63,685
  • sloc: cpp: 368,283; ansic: 33,988; python: 12,417; java: 12,203; awk: 5,879; sh: 1,846; xml: 655; perl: 405; php: 211; objc: 194; makefile: 77; sed: 2
file content (76 lines) | stat: -rw-r--r-- 3,741 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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
67
68
69
70
71
72
73
74
75
76
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */

#ifndef UPCAST_H
#define UPCAST_H

namespace upcast {
	template<class T> struct UnaryUpcast {};
	template<class U, class V> struct BinaryUpcast {};

	/* Get rid of const modifier */
	template<class T> struct UnaryUpcast<const T> { typedef typename UnaryUpcast<T>::type type; };

	/* To reduce size of the BinaryUpcast matrix, UnaryUpcast small types
	to (unsigned) int before attempting to BinaryUpcast them. */
	template<> struct UnaryUpcast<          bool  > { typedef   signed int  type; };
	template<> struct UnaryUpcast<   signed char  > { typedef   signed int  type; };
	template<> struct UnaryUpcast<   signed short > { typedef   signed int  type; };
	template<> struct UnaryUpcast<   signed int   > { typedef   signed int  type; };
	template<> struct UnaryUpcast<   signed long  > { typedef   signed long type; };
	template<> struct UnaryUpcast< unsigned char  > { typedef   signed int  type; };
	template<> struct UnaryUpcast< unsigned short > { typedef   signed int  type; };
	template<> struct UnaryUpcast< unsigned int   > { typedef unsigned int  type; };
	template<> struct UnaryUpcast< unsigned long  > { typedef unsigned long type; };
	template<> struct UnaryUpcast<          float > { typedef         float type; };
	template<> struct UnaryUpcast<         double > { typedef        double type; };
	template<> struct UnaryUpcast<    long double > { typedef   long double type; };

#define UPCAST1(U, V, W) \
	template<> struct BinaryUpcast<U,V> { typedef W type; }
#define UPCAST2(U, V, W) \
	template<> struct BinaryUpcast<U,V> { typedef W type; }; \
	template<> struct BinaryUpcast<V,U> { typedef W type; }

	/* Note: this was checked using GCC 4 on AMD64 */
	/*           param1    +    param2    --> return type  */
	UPCAST1(   signed int  ,   signed int  ,   signed int  );
	UPCAST2(   signed int  ,   signed long ,   signed int  );
	UPCAST2(   signed int  , unsigned int  , unsigned int  );
	UPCAST2(   signed int  , unsigned long , unsigned long );
	UPCAST2(   signed int  ,         float ,         float );
	UPCAST2(   signed int  ,        double ,        double );
	UPCAST2(   signed int  ,   long double ,   long double );
	UPCAST1(   signed long ,   signed long ,   signed long );
	UPCAST2(   signed long , unsigned int  ,   signed long );
	UPCAST2(   signed long , unsigned long , unsigned long );
	UPCAST2(   signed long ,         float ,         float );
	UPCAST2(   signed long ,        double ,        double );
	UPCAST2(   signed long ,   long double ,   long double );
	UPCAST1( unsigned int  , unsigned int  , unsigned int  );
	UPCAST2( unsigned int  , unsigned long , unsigned long );
	UPCAST2( unsigned int  ,         float ,         float );
	UPCAST2( unsigned int  ,        double ,        double );
	UPCAST2( unsigned int  ,   long double ,   long double );
	UPCAST1( unsigned long , unsigned long , unsigned long );
	UPCAST2( unsigned long ,         float ,         float );
	UPCAST2( unsigned long ,        double ,        double );
	UPCAST2( unsigned long ,   long double ,   long double );
	UPCAST1(         float ,         float ,         float );
	UPCAST2(         float ,        double ,        double );
	UPCAST2(         float ,   long double ,   long double );
	UPCAST1(        double ,        double ,        double );
	UPCAST2(        double ,   long double ,   long double );
	UPCAST1(   long double ,   long double ,   long double );

#undef UPCAST1
#undef UPCAST2

	template<class U, class V> struct Upcast {
		typedef typename BinaryUpcast<typename UnaryUpcast<U>::type, typename UnaryUpcast<V>::type>::type type;
	};

#define UPCAST(U, V) \
	typename upcast::Upcast< U, V >::type
}

#endif // UPCAST_H