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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
// Copyright 2005-2006 Alexander Nasonov.
// 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)
// Status of some compilers:
//
// Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
// /Za (disable extentions) is totally broken.
// /Ze (enable extentions) promotes UIntEnum incorrectly to int.
// See http://lab.msdn.microsoft.com/ProductFeedback/viewfeedback.aspx?feedbackid=22b0a6b7-120f-4ca0-9136-fa1b25b26efe
//
// Intel 9.0.028 for Windows has a similar problem:
// https://premier.intel.com/IssueDetail.aspx?IssueID=365073
//
// gcc 3.4.4 with -fshort-enums option on x86
// Dummy value is required, otherwise gcc promotes Enum1
// to unsigned int although USHRT_MAX <= INT_MAX.
// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24063
//
// CC: Sun WorkShop 6 update 2 C++ 5.3 Patch 111685-20 2004/03/19
// on SPARC V9 64-bit processor (-xarch=v9 flag)
// Dummy values are required for LongEnum3 and LongEnum4.
//
// CC: Sun C++ 5.7 Patch 117830-03 2005/07/21
// ICE in boost/type_traits/is_enum.hpp at line 67.
#include <climits>
#include "promote_util.hpp"
#include <boost/detail/workaround.hpp>
#ifdef BOOST_INTEL
// remark #1418: external function definition with no prior declaration
#pragma warning(disable:1418)
#endif
enum IntEnum1 { IntEnum1_min = -5 , IntEnum1_max = 5 };
enum IntEnum2 { IntEnum2_min = SHRT_MIN, IntEnum2_max = SHRT_MAX };
enum IntEnum3 { IntEnum3_min = INT_MIN , IntEnum3_max = INT_MAX };
enum IntEnum4 { IntEnum4_value = INT_MAX };
enum IntEnum5 { IntEnum5_value = INT_MIN };
void test_promote_to_int()
{
test_cv<IntEnum1,int>();
test_cv<IntEnum2,int>();
test_cv<IntEnum3,int>();
test_cv<IntEnum4,int>();
test_cv<IntEnum5,int>();
}
#if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ == 4 && USHRT_MAX <= INT_MAX)
enum Enum1 { Enum1_value = USHRT_MAX };
#else
// workaround for bug #24063 in gcc 3.4
// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24063
namespace gcc_short_enums_workaround {
enum short_enum { value = 1 };
template<bool ShortEnumsIsOn>
struct select
{
// Adding negative dummy value doesn't change
// promoted type because USHRT_MAX <= INT_MAX.
enum type { dummy = -1, value = USHRT_MAX };
};
template<>
struct select<false>
{
// No dummy value
enum type { value = USHRT_MAX };
};
} // namespace gcc_short_enums_workaround
typedef gcc_short_enums_workaround::select<
sizeof(gcc_short_enums_workaround::short_enum) != sizeof(int)
>::type Enum1;
#endif
void test_promote_to_int_or_uint()
{
#if USHRT_MAX <= INT_MAX
test_cv<Enum1, int>();
#else
test_cv<Enum1, unsigned int>();
#endif
}
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500) ) || \
BOOST_WORKAROUND(BOOST_INTEL_WIN, BOOST_TESTED_AT(1000))
// Don't test UIntEnum on VC++ 8.0 and Intel for Windows 9.0,
// they are broken. More info is on top of this file.
#else
enum UIntEnum { UIntEnum_max = UINT_MAX };
void test_promote_to_uint()
{
test_cv< UIntEnum, unsigned int >();
}
#endif
// Enums can't be promoted to [unsigned] long if sizeof(int) == sizeof(long).
#if INT_MAX < LONG_MAX
enum LongEnum1 { LongEnum1_min = -1 , LongEnum1_max = UINT_MAX };
enum LongEnum2 { LongEnum2_min = LONG_MIN, LongEnum2_max = LONG_MAX };
enum LongEnum3
{
LongEnum3_value = LONG_MAX
#if defined(__SUNPRO_CC) && __SUNPRO_CC <= 0x530
, LongEnum3_dummy = -1
#endif
};
enum LongEnum4
{
LongEnum4_value = LONG_MIN
#if defined(__SUNPRO_CC) && __SUNPRO_CC <= 0x530
, LongEnum4_dummy = 1
#endif
};
void test_promote_to_long()
{
test_cv< LongEnum1, long >();
test_cv< LongEnum2, long >();
test_cv< LongEnum3, long >();
test_cv< LongEnum4, long >();
}
enum ULongEnum { ULongEnum_value = ULONG_MAX };
void test_promote_to_ulong()
{
test_cv< ULongEnum, unsigned long >();
}
#endif // #if INT_MAX < LONG_MAX
int main()
{
return 0;
}
|