]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/contract/core/access.hpp
96d0a695960d7f6880226c026bce05eb8210cbbd
[ceph.git] / ceph / src / boost / boost / contract / core / access.hpp
1
2 #ifndef BOOST_CONTRACT_ACCESS_HPP_
3 #define BOOST_CONTRACT_ACCESS_HPP_
4
5 // Copyright (C) 2008-2018 Lorenzo Caminiti
6 // Distributed under the Boost Software License, Version 1.0 (see accompanying
7 // file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
8 // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
9
10 /** @file
11 Allow to declare invariants, base types, etc all as private members.
12 */
13
14 // IMPORTANT: Included by contract_macro.hpp so must #if-guard all its includes.
15 #include <boost/contract/core/config.hpp>
16 #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \
17 defined(BOOST_CONTRACT_STATIC_LINK)
18 #include <boost/contract/detail/decl.hpp>
19 #include <boost/contract/detail/type_traits/mirror.hpp>
20 #endif
21 #ifndef BOOST_CONTRACT_NO_INVARIANTS
22 #include <boost/contract/detail/debug.hpp>
23 #include <boost/function_types/property_tags.hpp>
24 #include <boost/mpl/vector.hpp>
25 #endif
26
27 namespace boost { namespace contract {
28
29 #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \
30 defined(BOOST_CONTRACT_STATIC_LINK)
31 class virtual_;
32
33 namespace detail {
34 BOOST_CONTRACT_DETAIL_DECL_DETAIL_COND_SUBCONTRACTING_Z(1,
35 /* is_friend = */ 0, OO, RR, FF, CC, AArgs);
36 }
37 #endif
38 #ifndef BOOST_CONTRACT_NO_INVARIANTS
39 namespace detail {
40 template<typename RR, class CC>
41 class cond_inv;
42 }
43 #endif
44
45 /**
46 Declare this class as friend to program invariants and base types as private
47 members.
48
49 Declare this class a friend of the user-defined class specifying the contracts
50 and then invariant functions and the base types @c typedef can be declared as
51 non-public members:
52
53 @code
54 class u
55 #define BASES public b, private w
56 : BASES
57 {
58 friend class boost::contract::access;
59
60 typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; // Private.
61 #undef BASES
62
63 void invariant() const { ... } // Private (same for static and volatile).
64
65 public:
66 ...
67 };
68 @endcode
69
70 In real code, programmers will likely chose to declare this class as friend so
71 to fully control public interfaces of their user-defined classes (this is not
72 extensively done in the examples of this documentation only for brevity).
73 This class is not intended to be directly used by programmers a part from
74 being declared as @c friend (and that is why this class does not have any public
75 member and it is not copyable).
76
77 @warning Not declaring this class friend of user-defined classes will cause
78 compiler errors on some compilers (e.g., MSVC) because the private
79 members needed to check the contracts will not be accessible.
80 On other compilers (e.g., GCC and CLang), the private access will
81 instead fail SFINAE and no compiler error will be reported while
82 invariants and subcontracting will be silently skipped at run-time.
83 Therefore, programmers must make sure to either declare this class
84 as friend or to always declare invariant functions and base types
85 @c typedef as public members.
86
87 @see @RefSect{advanced.access_specifiers, Access Specifiers}
88 */
89 class access { // Non-copyable (see below).
90 /** @cond */
91 private: // No public APIs (so users cannot use it directly by mistake).
92
93 access(); // Should never be constructed (not even internally).
94 ~access();
95
96 // No boost::noncopyable to avoid its overhead when contracts disabled.
97 access(access&);
98 access& operator=(access&);
99
100 #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \
101 defined(BOOST_CONTRACT_STATIC_LINK)
102 BOOST_CONTRACT_DETAIL_MIRROR_HAS_TYPE(has_base_types,
103 BOOST_CONTRACT_BASES_TYPEDEF)
104
105 template<class C>
106 struct base_types_of {
107 typedef typename C::BOOST_CONTRACT_BASES_TYPEDEF type;
108 };
109 #endif
110
111 #ifndef BOOST_CONTRACT_NO_INVARIANTS
112 BOOST_CONTRACT_DETAIL_MIRROR_HAS_MEMBER_FUNCTION(
113 has_static_invariant_f, BOOST_CONTRACT_STATIC_INVARIANT_FUNC)
114
115 BOOST_CONTRACT_DETAIL_MIRROR_HAS_STATIC_MEMBER_FUNCTION(
116 has_static_invariant_s, BOOST_CONTRACT_STATIC_INVARIANT_FUNC)
117
118 template<class C>
119 struct has_static_invariant : has_static_invariant_s<C, void,
120 boost::mpl::vector<> > {};
121
122 template<class C>
123 static void static_invariant() {
124 C::BOOST_CONTRACT_STATIC_INVARIANT_FUNC();
125 }
126
127 template<class C>
128 class static_invariant_addr { // Class so to pass it as tparam.
129 typedef void (*func_ptr)();
130 public:
131 static func_ptr apply() {
132 return &C::BOOST_CONTRACT_STATIC_INVARIANT_FUNC;
133 }
134 };
135
136 BOOST_CONTRACT_DETAIL_MIRROR_HAS_MEMBER_FUNCTION(
137 has_invariant_f, BOOST_CONTRACT_INVARIANT_FUNC)
138
139 BOOST_CONTRACT_DETAIL_MIRROR_HAS_STATIC_MEMBER_FUNCTION(
140 has_invariant_s, BOOST_CONTRACT_INVARIANT_FUNC)
141
142 template<class C>
143 struct has_cv_invariant : has_invariant_f<C, void, boost::mpl::vector<>,
144 boost::function_types::cv_qualified> {};
145
146 template<class C>
147 struct has_const_invariant : has_invariant_f<C, void, boost::mpl::
148 vector<>, boost::function_types::const_qualified> {};
149
150 template<class C>
151 static void cv_invariant(C const volatile* obj) {
152 BOOST_CONTRACT_DETAIL_DEBUG(obj);
153 obj->BOOST_CONTRACT_INVARIANT_FUNC();
154 }
155
156 template<class C>
157 static void const_invariant(C const* obj) {
158 BOOST_CONTRACT_DETAIL_DEBUG(obj);
159 obj->BOOST_CONTRACT_INVARIANT_FUNC();
160 }
161 #endif
162
163 // Friends (used to limit library's public API).
164 // NOTE: Using friends here and in all other places in this library
165 // does not increase compilation times (I experimented replacing all
166 // friends with public and got the same compilation times).
167 #if !defined(BOOST_CONTRACT_NO_CONDITIONS) || \
168 defined(BOOST_CONTRACT_STATIC_LINK)
169 BOOST_CONTRACT_DETAIL_DECL_DETAIL_COND_SUBCONTRACTING_Z(1,
170 /* is_friend = */ 1, OO, RR, FF, CC, AArgs);
171
172 BOOST_CONTRACT_DETAIL_DECL_FRIEND_OVERRIDING_PUBLIC_FUNCTIONS_Z(1,
173 OO, RR, FF, CC, AArgs, vv, rr, ff, oobj, aargs)
174 #endif
175 #ifndef BOOST_CONTRACT_NO_INVARIANTS
176 template<typename RR, class CC>
177 friend class boost::contract::detail::cond_inv;
178 #endif
179 /** @endcond */
180 };
181
182 } } // namespace
183
184 #endif // #include guard
185