BDE 4.39.x 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 `base`.
145 ///
146 /// \note Note that this method is supplied so that the only
147 /// publicly accessible constructor is the copy constructor.
148 static DegenerateFunctor cloneBaseObject(const FUNCTOR& base);
149
150 // CREATORS
151
152 /// Create a `DegenerateFunctor` having the same value the specified
153 /// `original`.
154 DegenerateFunctor(const DegenerateFunctor& original);
155
156 /// Create a `DegenerateFunctor` having the same value the specified
157 /// `original, and leave `original' in an unspecified (but valid) state.
159
160 // MANIPULATORS
161
162 /// Expose the overloaded function call operator from the parameterizing
163 /// class `FUNCTOR`.
164 using FUNCTOR::operator();
165
166 /// Swap the wrapped `FUNCTOR` object, by move-constructing a temporary
167 /// object from the specified `*other`, then alternately destroying and
168 /// in-place move-constructing new values for each of `*other` and `*this`.
169 ///
170 /// \note Note that this function is deliberately *not* named `swap`
171 /// as some "clever" template libraries may try to call a member-swap
172 /// function when they can find it, and ADL-swap is not available. Also
173 /// note that this overload is needed only so that the ADL-enabling
174 /// free-function `swap` can be defined, as the native std library
175 /// `std::swap` function will not accept this class (with its deliberate
176 /// degenerate nature) on AIX, or on Windows with Visual C++ prior to
177 /// VC2010.
179};
180
181/// Exchange the values of the specified `lhs` and `rhs` objects.
182template <class FUNCTOR>
185
186
187// ============================================================================
188// INLINE AND TEMPLATE FUNCTION IMPLEMENTATIONS
189// ============================================================================
190
191 // -----------------------
192 // class DegenerateFunctor
193 // -----------------------
194
195// CREATORS
196template <class FUNCTOR, bool ENABLE_SWAP>
197inline
199: FUNCTOR(base)
200{
201}
202
203template <class FUNCTOR, bool ENABLE_SWAP>
204inline
206 const DegenerateFunctor& original)
207: FUNCTOR(original)
208{
209}
210
211template <class FUNCTOR, bool ENABLE_SWAP>
212inline
215: FUNCTOR(bslmf::MovableRefUtil::move(static_cast<FUNCTOR&>(original)))
216{
217}
218
219template <class FUNCTOR, bool ENABLE_SWAP>
220inline
226
227template <class FUNCTOR, bool ENABLE_SWAP>
228inline
229void
231 DegenerateFunctor *other)
232{
233 BSLS_ASSERT_SAFE(other);
234
236 other->~DegenerateFunctor();
237 ::new((void *)other) DegenerateFunctor(bslmf::MovableRefUtil::move(*this));
238 this->~DegenerateFunctor();
239 ::new((void *)this) DegenerateFunctor(bslmf::MovableRefUtil::move(temp));
240}
241
242} // close package namespace
243
244template <class FUNCTOR>
245inline
246void bsltf::swap(DegenerateFunctor<FUNCTOR, true>& lhs,
247 DegenerateFunctor<FUNCTOR, true>& rhs)
248{
249 lhs.exchangeValues(bsls::Util::addressOf(rhs));
250}
251
252
253
254#endif
255
256// ----------------------------------------------------------------------------
257// Copyright 2013 Bloomberg Finance L.P.
258//
259// Licensed under the Apache License, Version 2.0 (the "License");
260// you may not use this file except in compliance with the License.
261// You may obtain a copy of the License at
262//
263// http://www.apache.org/licenses/LICENSE-2.0
264//
265// Unless required by applicable law or agreed to in writing, software
266// distributed under the License is distributed on an "AS IS" BASIS,
267// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
268// See the License for the specific language governing permissions and
269// limitations under the License.
270// ----------------------------- END-OF-FILE ----------------------------------
271
272/** @} */
273/** @} */
274/** @} */
Definition bslmf_movableref.h:752
Definition bsltf_degeneratefunctor.h:107
void exchangeValues(DegenerateFunctor *other)
Definition bsltf_degeneratefunctor.h:230
static DegenerateFunctor cloneBaseObject(const FUNCTOR &base)
Definition bsltf_degeneratefunctor.h:222
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1917
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition bdlbb_blob.h:579
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:1067
static TYPE * addressOf(TYPE &obj)
Definition bsls_util.h:312