blob: 7ee8c58f9e41fee6b334eeeea2a429d54a10a583 [file] [log] [blame]
Jeff Thompson86b6d642013-10-17 15:01:56 -07001// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
2// (C) Copyright 2005-2007 Jonathan Turkanis
3// (C) Copyright David Abrahams 2004.
4// Distributed under the Boost Software License, Version 1.0. (See accompanying
5// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
6
7// See http://www.boost.org/libs/iostreams for documentation.
8
9#ifndef NDNBOOST_IOSTREAMS_DETAIL_IS_DEREFERENCEABLE_HPP_INCLUDED
10#define NDNBOOST_IOSTREAMS_DETAIL_IS_DEREFERENCEABLE_HPP_INCLUDED
11
12# include <ndnboost/type_traits/detail/bool_trait_def.hpp>
13# include <ndnboost/type_traits/detail/template_arity_spec.hpp>
14# include <ndnboost/type_traits/remove_cv.hpp>
15# include <ndnboost/mpl/aux_/lambda_support.hpp>
16# include <ndnboost/mpl/bool.hpp>
17# include <ndnboost/detail/workaround.hpp>
18
19namespace ndnboost { namespace iostreams { namespace detail {
20
21// is_dereferenceable<T> metafunction
22//
23// Requires: Given x of type T&, if the expression *x is well-formed
24// it must have complete type; otherwise, it must neither be ambiguous
25// nor violate access.
26
27// This namespace ensures that ADL doesn't mess things up.
28namespace is_dereferenceable_
29{
30 // a type returned from operator* when no increment is found in the
31 // type's own namespace
32 struct tag {};
33
34 // any soaks up implicit conversions and makes the following
35 // operator* less-preferred than any other such operator that
36 // might be found via ADL.
37 struct any { template <class T> any(T const&); };
38
39 // This is a last-resort operator* for when none other is found
40 tag operator*(any const&);
41
42# if NDNBOOST_WORKAROUND(__MWERKS__, NDNBOOST_TESTED_AT(0x3202)) \
43 || NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300)
44# define NDNBOOST_comma(a,b) (a)
45# else
46 // In case an operator++ is found that returns void, we'll use ++x,0
47 tag operator,(tag,int);
48# define NDNBOOST_comma(a,b) (a,b)
49# endif
50
51 // two check overloads help us identify which operator++ was picked
52 char (& check_increment(tag) )[2];
53
54 template <class T>
55 char check_increment(T const&);
56
57 template <class T>
58 struct impl
59 {
60 static typename ndnboost::remove_cv<T>::type& x;
61
62 NDNBOOST_STATIC_CONSTANT(
63 bool
64 , value = sizeof(is_dereferenceable_::check_increment(NDNBOOST_comma(*x,0))) == 1
65 );
66 };
67}
68
69# undef NDNBOOST_comma
70
71template<typename T>
72struct is_dereferenceable
73 NDNBOOST_TT_AUX_BOOL_C_BASE(is_dereferenceable_::impl<T>::value)
74{
75 NDNBOOST_TT_AUX_BOOL_TRAIT_VALUE_DECL(is_dereferenceable_::impl<T>::value)
76 NDNBOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_dereferenceable,(T))
77};
78
79} }
80
81NDNBOOST_TT_AUX_TEMPLATE_ARITY_SPEC(1, ::ndnboost::iostreams::detail::is_dereferenceable)
82
83} // End namespaces detail, iostreams, boost.
84
85#endif // NDNBOOST_IOSTREAMS_DETAIL_IS_DEREFERENCEABLE_HPP_INCLUDED