blob: b30e90d131b39a411b48c6b10cdb94f8d7be4243 [file] [log] [blame]
Jeff Thompsona28eed82013-08-22 16:21:10 -07001
2// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
3// Use, modification and distribution are subject to the Boost Software License,
4// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
5// http://www.boost.org/LICENSE_1_0.txt).
6//
7// See http://www.boost.org/libs/type_traits for most recent version including documentation.
8
9#ifndef BOOST_TT_IS_EMPTY_HPP_INCLUDED
10#define BOOST_TT_IS_EMPTY_HPP_INCLUDED
11
12#include <ndnboost/type_traits/is_convertible.hpp>
13#include <ndnboost/type_traits/detail/ice_or.hpp>
14#include <ndnboost/type_traits/config.hpp>
15#include <ndnboost/type_traits/intrinsics.hpp>
16
17#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
18# include <ndnboost/type_traits/remove_cv.hpp>
19# include <ndnboost/type_traits/is_class.hpp>
20# include <ndnboost/type_traits/add_reference.hpp>
21#else
22# include <ndnboost/type_traits/is_reference.hpp>
23# include <ndnboost/type_traits/is_pointer.hpp>
24# include <ndnboost/type_traits/is_member_pointer.hpp>
25# include <ndnboost/type_traits/is_array.hpp>
26# include <ndnboost/type_traits/is_void.hpp>
27# include <ndnboost/type_traits/detail/ice_and.hpp>
28# include <ndnboost/type_traits/detail/ice_not.hpp>
29#endif
30
31// should be always the last #include directive
32#include <ndnboost/type_traits/detail/bool_trait_def.hpp>
33
34#ifndef BOOST_INTERNAL_IS_EMPTY
35#define BOOST_INTERNAL_IS_EMPTY(T) false
36#else
37#define BOOST_INTERNAL_IS_EMPTY(T) BOOST_IS_EMPTY(T)
38#endif
39
40namespace ndnboost {
41
42namespace detail {
43
44#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
45
46#ifdef BOOST_MSVC
47#pragma warning(push)
48#pragma warning(disable:4624) // destructor could not be generated
49#endif
50
51template <typename T>
52struct empty_helper_t1 : public T
53{
54 empty_helper_t1(); // hh compiler bug workaround
55 int i[256];
56private:
57 // suppress compiler warnings:
58 empty_helper_t1(const empty_helper_t1&);
59 empty_helper_t1& operator=(const empty_helper_t1&);
60};
61
62#ifdef BOOST_MSVC
63#pragma warning(pop)
64#endif
65
66struct empty_helper_t2 { int i[256]; };
67
68#if !BOOST_WORKAROUND(__BORLANDC__, < 0x600)
69
70template <typename T, bool is_a_class = false>
71struct empty_helper
72{
73 BOOST_STATIC_CONSTANT(bool, value = false);
74};
75
76template <typename T>
77struct empty_helper<T, true>
78{
79 BOOST_STATIC_CONSTANT(
80 bool, value = (sizeof(empty_helper_t1<T>) == sizeof(empty_helper_t2))
81 );
82};
83
84template <typename T>
85struct is_empty_impl
86{
87 typedef typename remove_cv<T>::type cvt;
88 BOOST_STATIC_CONSTANT(
89 bool, value = (
90 ::ndnboost::type_traits::ice_or<
91 ::ndnboost::detail::empty_helper<cvt,::ndnboost::is_class<T>::value>::value
92 , BOOST_INTERNAL_IS_EMPTY(cvt)
93 >::value
94 ));
95};
96
97#else // __BORLANDC__
98
99template <typename T, bool is_a_class, bool convertible_to_int>
100struct empty_helper
101{
102 BOOST_STATIC_CONSTANT(bool, value = false);
103};
104
105template <typename T>
106struct empty_helper<T, true, false>
107{
108 BOOST_STATIC_CONSTANT(bool, value = (
109 sizeof(empty_helper_t1<T>) == sizeof(empty_helper_t2)
110 ));
111};
112
113template <typename T>
114struct is_empty_impl
115{
116 typedef typename remove_cv<T>::type cvt;
117 typedef typename add_reference<T>::type r_type;
118
119 BOOST_STATIC_CONSTANT(
120 bool, value = (
121 ::ndnboost::type_traits::ice_or<
122 ::ndnboost::detail::empty_helper<
123 cvt
124 , ::ndnboost::is_class<T>::value
125 , ::ndnboost::is_convertible< r_type,int>::value
126 >::value
127 , BOOST_INTERNAL_IS_EMPTY(cvt)
128 >::value));
129};
130
131#endif // __BORLANDC__
132
133#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
134
135#ifdef BOOST_MSVC6_MEMBER_TEMPLATES
136
137template <typename T>
138struct empty_helper_t1 : public T
139{
140 empty_helper_t1();
141 int i[256];
142};
143
144struct empty_helper_t2 { int i[256]; };
145
146template <typename T>
147struct empty_helper_base
148{
149 enum { value = (sizeof(empty_helper_t1<T>) == sizeof(empty_helper_t2)) };
150};
151
152template <typename T>
153struct empty_helper_nonbase
154{
155 enum { value = false };
156};
157
158template <bool base>
159struct empty_helper_chooser
160{
161 template <typename T> struct result_
162 {
163 typedef empty_helper_nonbase<T> type;
164 };
165};
166
167template <>
168struct empty_helper_chooser<true>
169{
170 template <typename T> struct result_
171 {
172 typedef empty_helper_base<T> type;
173 };
174};
175
176template <typename T>
177struct is_empty_impl
178{
179 typedef ::ndnboost::detail::empty_helper_chooser<
180 ::ndnboost::type_traits::ice_and<
181 ::ndnboost::type_traits::ice_not< ::ndnboost::is_reference<T>::value >::value,
182 ::ndnboost::type_traits::ice_not< ::ndnboost::is_convertible<T,double>::value >::value,
183 ::ndnboost::type_traits::ice_not< ::ndnboost::is_pointer<T>::value >::value,
184 ::ndnboost::type_traits::ice_not< ::ndnboost::is_member_pointer<T>::value >::value,
185 ::ndnboost::type_traits::ice_not< ::ndnboost::is_array<T>::value >::value,
186 ::ndnboost::type_traits::ice_not< ::ndnboost::is_void<T>::value >::value,
187 ::ndnboost::type_traits::ice_not<
188 ::ndnboost::is_convertible<T,void const volatile*>::value
189 >::value
190 >::value > chooser;
191
192 typedef typename chooser::template result_<T> result;
193 typedef typename result::type eh_type;
194
195 BOOST_STATIC_CONSTANT(bool, value =
196 (::ndnboost::type_traits::ice_or<eh_type::value, BOOST_INTERNAL_IS_EMPTY(T)>::value));
197};
198
199#else
200
201template <typename T> struct is_empty_impl
202{
203 BOOST_STATIC_CONSTANT(bool, value = BOOST_INTERNAL_IS_EMPTY(T));
204};
205
206#endif // BOOST_MSVC6_MEMBER_TEMPLATES
207
208#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
209
210// these help when the compiler has no partial specialization support:
211BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_empty,void,false)
212#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
213BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_empty,void const,false)
214BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_empty,void volatile,false)
215BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_empty,void const volatile,false)
216#endif
217
218} // namespace detail
219
220BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_empty,T,::ndnboost::detail::is_empty_impl<T>::value)
221
222} // namespace ndnboost
223
224#include <ndnboost/type_traits/detail/bool_trait_undef.hpp>
225
226#undef BOOST_INTERNAL_IS_EMPTY
227
228#endif // BOOST_TT_IS_EMPTY_HPP_INCLUDED
229