1 // RUN: %llvmgxx -S %s -o - -O2 | FileCheck %s
4 template <typename T
> struct cv_traits_imp
{};
5 template <typename T
> struct cv_traits_imp
<T
*> {typedef T unqualified_type
;};
10 namespace mpl
{using namespace mpl_
;}
11 template< typename T
> struct remove_cv
{typedef typename
boost::detail::cv_traits_imp
<T
*>::unqualified_type type
;};
12 namespace type_traits
{
13 typedef char yes_type
;
14 struct no_type
{char padding
[8];};
18 template< bool C_
> struct bool_
;
19 typedef bool_
<true> true_
;
20 typedef bool_
<false> false_
;
21 template< bool C_
> struct bool_
{static const bool value
= C_
;};
22 template< typename T
, T N
> struct integral_c
;
25 template <class T
, T val
> struct integral_constant
:
26 public mpl::integral_c
<T
, val
> {};
27 template<> struct integral_constant
<bool,true> : public mpl::true_
{};
28 template<> struct integral_constant
<bool,false> : public mpl::false_
{};
29 namespace type_traits
{
30 template <bool b1
, bool b2
, bool b3
= false, bool b4
= false,
31 bool b5
= false, bool b6
= false, bool b7
= false> struct ice_or
;
32 template <bool b1
, bool b2
, bool b3
, bool b4
, bool b5
, bool b6
, bool b7
>
33 struct ice_or
{static const bool value
= true; };
34 template <> struct ice_or
<false, false, false, false, false, false, false>
35 {static const bool value
= false;};
36 template <bool b1
, bool b2
, bool b3
= true, bool b4
= true, bool b5
= true,
37 bool b6
= true, bool b7
= true> struct ice_and
;
38 template <bool b1
, bool b2
, bool b3
, bool b4
, bool b5
, bool b6
, bool b7
>
39 struct ice_and
{static const bool value
= false;};
40 template <> struct ice_and
<true, true, true, true, true, true, true>
41 {static const bool value
= true;};
42 template <bool b
> struct ice_not
{static const bool value
= true;};
45 template <typename T
> struct is_union_impl
{static const bool value
= false;};
47 template< typename T
> struct is_union
:
48 ::boost::integral_constant
<bool, ::boost::detail::is_union_impl
<T
>::value
> {};
50 template <class U
> ::boost::type_traits::yes_type
is_class_tester(void(U::*)(void));
51 template <class U
> ::boost::type_traits::no_type
is_class_tester(...);
52 template <typename T
> struct is_class_impl
{
53 static const bool value
= (::boost::type_traits::ice_and
< sizeof(is_class_tester
<T
>(0))
54 == sizeof(::boost::type_traits::yes_type
),
55 ::boost::type_traits::ice_not
< ::boost::is_union
<T
>::value
>::value
>::value
);};
57 template<typename T
> struct is_class
:
58 ::boost::integral_constant
<bool,::boost::detail::is_class_impl
<T
>::value
> { };
60 template <typename T
> struct empty_helper_t1
: public T
{int i
[256];};
61 struct empty_helper_t2
{int i
[256];};
62 template <typename T
, bool is_a_class
= false> struct empty_helper
63 {static const bool value
= false;};
64 template <typename T
> struct empty_helper
<T
, true>
65 {static const bool value
= (sizeof(empty_helper_t1
<T
>) == sizeof(empty_helper_t2
));};
66 template <typename T
> struct is_empty_impl
{
67 typedef typename remove_cv
<T
>::type cvt
;
68 static const bool value
= (::boost::type_traits::ice_or
< ::boost::detail::empty_helper
69 <cvt
,::boost::is_class
<T
>::value
>::value
, false>::value
);
72 template<typename T
> struct is_empty
:
73 ::boost::integral_constant
<bool,::boost::detail::is_empty_impl
<T
>::value
> {};
74 template<typename T
, typename U
> struct is_same
:
75 ::boost::integral_constant
<bool,false> {};
76 template<typename T
> struct call_traits
{typedef T
& reference
;};
78 template <class T1
, class T2
, bool IsSame
, bool FirstEmpty
, bool SecondEmpty
>
79 struct compressed_pair_switch
;
80 template <class T1
, class T2
>
81 struct compressed_pair_switch
<T1
, T2
, false, true, false>
82 {static const int value
= 1;};
83 template <class T1
, class T2
, int Version
> class compressed_pair_imp
;
84 template <class T1
, class T2
> class compressed_pair_imp
<T1
, T2
, 1>:
85 protected ::boost::remove_cv
<T1
>::type
{
87 typedef T1 first_type
;
88 typedef T2 second_type
;
89 typedef typename call_traits
<first_type
>::reference first_reference
;
90 typedef typename call_traits
<second_type
>::reference second_reference
;
91 first_reference
first() {return *this;}
92 second_reference
second() {return second_
;}
96 template <class T1
, class T2
> class compressed_pair
:
97 private ::boost::details::compressed_pair_imp
<T1
, T2
, ::boost::details::compressed_pair_switch
<
98 T1
, T2
, ::boost::is_same
<typename remove_cv
<T1
>::type
,
99 typename remove_cv
<T2
>::type
>::value
,
100 ::boost::is_empty
<T1
>::value
, ::boost::is_empty
<T2
>::value
>::value
>
103 typedef details::compressed_pair_imp
<T1
, T2
, ::boost::details::compressed_pair_switch
<
104 T1
, T2
, ::boost::is_same
<typename remove_cv
<T1
>::type
,
105 typename remove_cv
<T2
>::type
>::value
,
106 ::boost::is_empty
<T1
>::value
, ::boost::is_empty
<T2
>::value
>::value
> base
;
108 typedef T1 first_type
;
109 typedef T2 second_type
;
110 typedef typename call_traits
<first_type
>::reference first_reference
;
111 typedef typename call_traits
<second_type
>::reference second_reference
;
112 first_reference
first() {return base::first();}
113 second_reference
second() {return base::second();}
116 struct empty_base_t
{};
117 struct empty_t
: empty_base_t
{};
118 typedef boost::compressed_pair
<empty_t
, int> data_t
;
119 extern "C" {int printf(const char * , ...);}
120 extern "C" {void abort(void);}
121 int main (int argc
, char * const argv
[]) {
124 // This store should be elided:
125 x
.first() = empty_t();
126 // If x.second() has been clobbered by the elided store, fail.
127 if (x
.second() != -3) {
128 printf("x.second() was clobbered\n");
129 // CHECK-NOT: x.second() was clobbered