BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bsltf_degeneratefunctor.h
Go to the documentation of this file.
1/// @file bsltf_degeneratefunctor.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bsltf_degeneratefunctor.h -*-C++-*-
8#ifndef INCLUDED_BSLTF_DEGENERATEFUNCTOR
9#define INCLUDED_BSLTF_DEGENERATEFUNCTOR
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bsltf_degeneratefunctor bsltf_degeneratefunctor
15/// @brief Provide an awkward type to adapt a user-supplied functor.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bsltf
19/// @{
20/// @addtogroup bsltf_degeneratefunctor
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bsltf_degeneratefunctor-purpose"> Purpose</a>
25/// * <a href="#bsltf_degeneratefunctor-classes"> Classes </a>
26/// * <a href="#bsltf_degeneratefunctor-description"> Description </a>
27/// * <a href="#bsltf_degeneratefunctor-usage"> Usage </a>
28/// * <a href="#bsltf_degeneratefunctor-example-1-tbd"> Example 1: TBD </a>
29///
30/// # Purpose {#bsltf_degeneratefunctor-purpose}
31/// Provide an awkward type to adapt a user-supplied functor.
32///
33/// # Classes {#bsltf_degeneratefunctor-classes}
34///
35/// - bsltf::DegenerateFunctor: awkward type that adapts a user-supplied functor
36///
37/// @see bsltf_templatetestfacility
38///
39/// # Description {#bsltf_degeneratefunctor-description}
40/// This component provides a functor adaptor, primarily for use
41/// when testing templates that make use of Callable template parameters. The
42/// adaptor defined in this component provides an interface that is purposefully
43/// as awkward as possible, yet should accepted by generic code, particularly
44/// code conforming to the widest interpretation of the C++ standard library.
45/// Many common operations that would be implicitly supplied, such as the
46/// address-of operator and the comma operator, are explicitly disabled. While
47/// the adapter remains CopyConstructible so that it may be used as a member of
48/// a class, such as a standard container, it is not CopyAssignable, and so
49/// typically is not Swappable. An additional boolean template argument
50/// optionally creates an adapter that supports swapping.
51///
52/// ## Usage {#bsltf_degeneratefunctor-usage}
53///
54///
55/// This section illustrates intended use of this component.
56///
57/// ### Example 1: TBD {#bsltf_degeneratefunctor-example-1-tbd}
58///
59///
60/// @}
61/** @} */
62/** @} */
63
64/** @addtogroup bsl
65 * @{
66 */
67/** @addtogroup bsltf
68 * @{
69 */
70/** @addtogroup bsltf_degeneratefunctor
71 * @{
72 */
73
74#include <bslscm_version.h>
75
76#include <bslmf_movableref.h>
77
78#include <bsls_assert.h>
79#include <bsls_util.h>
80
81#include <new>
82
83
84
85namespace bsltf {
86
87 // =======================
88 // class DegenerateFunctor
89 // =======================
90
91/// This test class template adapts a CopyConstructible class to offer
92/// a minimal or outright obstructive interface for testing generic code.
93/// To support the testing of standard containers, this adapter will be
94/// MoveConstructible, CopyConstructible, and nothrow Destructible as long
95/// as the adapted `FUNCTOR` satisfies the same requirements. This class
96/// will further be Swappable if (the template parameter) `ENABLE_SWAP` is
97/// `true` and the adapted `FUNCTOR` is MoveConstructible. The (inherited)
98/// function call operator should be the only other available method, no
99/// other operation (e.g., the unary address-of operator) should be usable.
100/// We take advantage of the fact that defining a copy constructor inhibits
101/// the generation of a default constructor, and that constructors are not
102/// inherited by a derived class. `DegenerateFunctor` objects must be
103/// created through either the copy constructor, or by wrapping a `FUNCTOR`
104/// object through the static factory method of this class,
105/// `cloneBaseObject`.
106template <class FUNCTOR, bool ENABLE_SWAP = true>
107class DegenerateFunctor : private FUNCTOR {
108
109 private:
110 // PRIVATE CREATORS
111
112 /// Create a `DegenerateFunctor` wrapping a copy of the specified
113 /// `base`.
114 explicit DegenerateFunctor(const FUNCTOR& base);
115
116 private:
117 // NOT IMPLEMENTED
118
119 /// Not implemented
120 DegenerateFunctor& operator=(const DegenerateFunctor&); // = delete;
121
122 /// not implemented
123 void operator&(); // = delete;
124
125 /// not implemented
126 template<class T>
127 void operator,(const T&); // = delete;
128
129 /// not implemented
130 template<class T>
131 void operator,(T&); // = delete;
132
133 /// Not implemented. This method hides a frequently supplied member
134 /// function that may be sniffed out by clever template code when it
135 /// is declared in the base class. When `ENABLE_SWAP` is `false`, we
136 /// want to be sure that this class does not accidentally allow
137 /// swapping through an unexpected back door. When `ENABLE_SWAP` is
138 /// `true`, we provide a differently named hook, to minimize the chance
139 /// that a clever template library can sniff it out.
140 template<class T>
141 void swap(T&); // = delete;
142
143 public:
144 /// Create a DegenerateFunctor object wrapping a copy of the specified
145 /// `base`. Note that this method is supplied so that the only
146 /// publicly accessible constructor is the copy constructor.
147 static DegenerateFunctor cloneBaseObject(const FUNCTOR& base);
148
149 // CREATORS
150
151 /// Create a `DegenerateFunctor` having the same value the specified
152 /// `original`.
153 DegenerateFunctor(const DegenerateFunctor& original);
154
155 /// Create a `DegenerateFunctor` having the same value the specified
156 /// `original, and leave `original' in an unspecified (but valid) state.
158
159 // MANIPULATORS
160
161 /// Expose the overloaded function call operator from the parameterizing
162 /// class `FUNCTOR`.
163 using FUNCTOR::operator();
164
165 /// Swap the wrapped `FUNCTOR` object, by move-constructing a temporary
166 /// object from the specified `*other`, then alternately destroying and
167 /// in-place move-constructing new values for each of `*other` and
168 /// `*this`. Note that this function is deliberately *not* named `swap`
169 /// as some "clever" template libraries may try to call a member-swap
170 /// function when they can find it, and ADL-swap is not available. Also
171 /// note that this overload is needed only so that the ADL-enabling
172 /// free-function `swap` can be defined, as the native std library
173 /// `std::swap` function will not accept this class (with its deliberate
174 /// degenerate nature) on AIX, or on Windows with Visual C++ prior to
175 /// VC2010.
177};
178
179/// Exchange the values of the specified `lhs` and `rhs` objects.
180template <class FUNCTOR>
183
184
185// ============================================================================
186// INLINE AND TEMPLATE FUNCTION IMPLEMENTATIONS
187// ============================================================================
188
189 // -----------------------
190 // class DegenerateFunctor
191 // -----------------------
192
193// CREATORS
194template <class FUNCTOR, bool ENABLE_SWAP>
195inline
197: FUNCTOR(base)
198{
199}
200
201template <class FUNCTOR, bool ENABLE_SWAP>
202inline
204 const DegenerateFunctor& original)
205: FUNCTOR(original)
206{
207}
208
209template <class FUNCTOR, bool ENABLE_SWAP>
210inline
213: FUNCTOR(bslmf::MovableRefUtil::move(static_cast<FUNCTOR&>(original)))
214{
215}
216
217template <class FUNCTOR, bool ENABLE_SWAP>
218inline
224
225template <class FUNCTOR, bool ENABLE_SWAP>
226inline
227void
229 DegenerateFunctor *other)
230{
231 BSLS_ASSERT_SAFE(other);
232
234 other->~DegenerateFunctor();
235 ::new((void *)other) DegenerateFunctor(bslmf::MovableRefUtil::move(*this));
236 this->~DegenerateFunctor();
237 ::new((void *)this) DegenerateFunctor(bslmf::MovableRefUtil::move(temp));
238}
239
240} // close package namespace
241
242template <class FUNCTOR>
243inline
244void bsltf::swap(DegenerateFunctor<FUNCTOR, true>& lhs,
245 DegenerateFunctor<FUNCTOR, true>& rhs)
246{
247 lhs.exchangeValues(bsls::Util::addressOf(rhs));
248}
249
250
251
252#endif
253
254// ----------------------------------------------------------------------------
255// Copyright 2013 Bloomberg Finance L.P.
256//
257// Licensed under the Apache License, Version 2.0 (the "License");
258// you may not use this file except in compliance with the License.
259// You may obtain a copy of the License at
260//
261// http://www.apache.org/licenses/LICENSE-2.0
262//
263// Unless required by applicable law or agreed to in writing, software
264// distributed under the License is distributed on an "AS IS" BASIS,
265// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
266// See the License for the specific language governing permissions and
267// limitations under the License.
268// ----------------------------- END-OF-FILE ----------------------------------
269
270/** @} */
271/** @} */
272/** @} */
Definition bslmf_movableref.h:751
Definition bsltf_degeneratefunctor.h:107
void exchangeValues(DegenerateFunctor *other)
Definition bsltf_degeneratefunctor.h:228
static DegenerateFunctor cloneBaseObject(const FUNCTOR &base)
Definition bsltf_degeneratefunctor.h:220
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bdlbb_blob.h:576
Definition bsltf_allocargumenttype.h:92
void swap(DegenerateFunctor< FUNCTOR, true > &lhs, DegenerateFunctor< FUNCTOR, true > &rhs)
Exchange the values of the specified lhs and rhs objects.
static MovableRef< t_TYPE > move(t_TYPE &reference) BSLS_KEYWORD_NOEXCEPT
Definition bslmf_movableref.h:1060
static TYPE * addressOf(TYPE &obj)
Definition bsls_util.h:305