Skip to content

Commit

Permalink
Merge pull request #5079 from afeher/drqs-177179750-unwrap_ref-work
Browse files Browse the repository at this point in the history
Implement unwrap_reference, unwrap_ref_decay.
  • Loading branch information
cppguru authored and GitHub Enterprise committed Dec 10, 2024
2 parents b5a95bd + 7577d38 commit 5aa9844
Show file tree
Hide file tree
Showing 16 changed files with 2,024 additions and 641 deletions.
4 changes: 3 additions & 1 deletion groups/bsl/bsl+bslhdrs/bsl_functional.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,9 @@ namespace bsl {
#include <bslstl_equalto.h>
#include <bslstl_function.h>
#include <bslstl_hash.h>
#include <bslstl_referencewrapper.h>
#include <bslmf_referencewrapper.h>
#include <bslmf_unwraprefdecay.h>
#include <bslmf_unwrapreference.h>


#endif // INCLUDED_BSL_FUNCTIONAL
Expand Down
3 changes: 3 additions & 0 deletions groups/bsl/bsl+bslhdrs/bsl_type_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -651,11 +651,14 @@ using std::void_t;
#include <bslmf_isvolatile.h>
#include <bslmf_removeconst.h>
#include <bslmf_removecv.h>
#include <bslmf_removecvref.h>
#include <bslmf_removeextent.h>
#include <bslmf_removepointer.h>
#include <bslmf_removereference.h>
#include <bslmf_removevolatile.h>
#include <bslmf_typeidentity.h>
#include <bslmf_unwraprefdecay.h>
#include <bslmf_unwrapreference.h>
#include <bslmf_voidtype.h>

#endif
Expand Down
21 changes: 21 additions & 0 deletions groups/bsl/bslmf/bslmf_referencewrapper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// bslmf_referencewrapper.cpp -*-C++-*-
#include <bslmf_referencewrapper.h>

#include <bsls_ident.h>
BSLS_IDENT("$Id$ $CSID$")

// ----------------------------------------------------------------------------
// Copyright 2013 Bloomberg Finance L.P.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------- END-OF-FILE ----------------------------------
288 changes: 288 additions & 0 deletions groups/bsl/bslmf/bslmf_referencewrapper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,288 @@
// bslmf_referencewrapper.h -*-C++-*-
#ifndef INCLUDED_BSLMF_REFERENCEWRAPPER
#define INCLUDED_BSLMF_REFERENCEWRAPPER

#include <bsls_ident.h>
BSLS_IDENT("$Id: $")

//@PURPOSE: Provide copyable, assignable object wrapper for references.
//
//@CLASSES:
// bsl::reference_wrapper: class object to hold a reference to an object
//
//@CANONICAL_HEADER: bsl_functional.h
//
//@DESCRIPTION: This component provides `bsl::reference_wrapper`, a reduced
// implementation of the standard C++2011 template of the same name, which
// simply wraps a reference into a copyable, assignable object to allow it to
// be stored in a place that cannot normally hold a reference, such as a
// standard container. Because a reference wrapper is convertible to its
// contained reference type, it can be passed to functions that take such a
// reference.
//
// This component also provides the (free) helper functions `bsl::ref` and
// `bsl::cref` that may be used to generate `reference_wrapper` objects more
// concisely than with the constructor.
//
// NOTE: This component is a partial implementation of the standard class,
// omitting support for use as a function object, and is in any case of
// limited usefulness in a pure C++98 environment.
//
///Usage
///-----
// This section illustrates intended use of this component.
//
///Example 1: Sorted References
/// - - - - - - - - - - - - - -
// Let us suppose that we wish to handle objects that will be passed to a
// comparison function expecting references to the objects. Let us suppose
// further that these objects are large enough that we would not wish to move
// them around bodily as they are sorted. Note that plausible examples of uses
// for this component are limited in freestanding C++98.
//
// First, let us define the large-object type:
// ```
// struct Canary {
// static const int s_size = 1000;
// Canary *d_values[s_size];
// Canary();
// };
//
// Canary::Canary()
// {
// for (int i = 0; i < s_size; ++i) {
// d_values[i] = this;
// }
// }
// ```
// Next, we define the comparison function:
// ```
// bool operator<(Canary const& a, Canary const& b)
// {
// return a.d_values[0] < b.d_values[0];
// }
// ```
// Finally, we define a generic function to sort two items:
// ```
// template <typename T>
// void sortTwoItems(T& a, T& b)
// {
// if (b < a) {
// T tmp(a);
// a = b;
// b = tmp;
// }
// }
// ```
// We can call `sortTwoItems` on wrappers representing `Canary` objects
// without need to move actual, large `Canary` objects about. In the call to
// `sortTwoItems`, below, the `operator=` used in it is that of
// `bsl::reference_wrapper<Canary>`, but the `operator<` used is the one
// declared for `Canary&` arguments. All of the conversions needed are
// applied implicitly:
// ```
// Canary canaries[2];
// bsl::reference_wrapper<Canary> canaryA = bsl::ref(canaries[1]);
// bsl::reference_wrapper<Canary> canaryB = bsl::ref(canaries[0]);
// sortTwoItems(canaryA, canaryB);
//
// assert(&canaryA.get() == canaries);
// assert(&canaryB.get() == canaries + 1);
// ```

#include <bslscm_version.h>

#include <bslmf_isbitwisemoveable.h>
#include <bslmf_isreferencewrapper.h>

#include <bsls_keyword.h>
#include <bsls_libraryfeatures.h>
#include <bsls_util.h> // for BloombergLP::bsls::Util::addressOf

#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
#include <functional>

#define BSLMF_REFERENCEWRAPPER_IS_ALIASED

namespace bsl {
using std::cref;
using std::ref;
using std::reference_wrapper;
} // close enterprise namespace
#endif

#ifndef BSLMF_REFERENCEWRAPPER_IS_ALIASED
namespace bsl {

// =======================
// class reference_wrapper
// =======================

/// This class is a wrapper that encapsulates an object reference, enabling
/// operations not possible on actual references, including assignment,
/// copying, and storage in standard containers. When stored in a
/// container, it enables functions defined to operate on references to the
/// type represented to be called on the container elements.
template <class T>
class reference_wrapper {

private:
// DATA
T *d_represented_p; // the represented object (not owned)

public:
// TYPES
typedef T type;

// CREATORS

/// Create a reference wrapper representing the specified `object`.
reference_wrapper(T& object) BSLS_KEYWORD_NOEXCEPT; // IMPLICIT

//! reference_wrapper(const reference_wrapper& original) = default;
// Create a reference wrapper referring to the same object as the
// specified 'original'.

//! ~reference_wrapper() = default;
// Destroy this object.

// MANIPULATORS
//! reference_wrapper& operator=(const reference_wrapper& rhs) = default;
// Assign this object to refer to the same object as the specified
// 'rhs', and return '*this'.

// ACCESSORS

/// Return a reference to the object that `*this` represents.
T& get() const BSLS_KEYWORD_NOEXCEPT;

/// Return a reference to the object that `*this` represents.
operator T&() const BSLS_KEYWORD_NOEXCEPT;
};

// FREE FUNCTIONS

/// Return a reference wrapper representing a `const` view of the specified
/// `object`.
template <class T>
reference_wrapper<const T> cref(const T& object) BSLS_KEYWORD_NOEXCEPT;

template <class T>
reference_wrapper<const T> cref(reference_wrapper<T> original)
BSLS_KEYWORD_NOEXCEPT;
// Return a reference wrapper representing a 'const' view of the same
// object as the specified 'original'.

/// Return a reference wrapper that represents the specified `object`.
template <class T>
reference_wrapper<T> ref(T& object) BSLS_KEYWORD_NOEXCEPT;

/// Return a reference wrapper that represents the same object as the
/// specified `original`.
template <class T>
reference_wrapper<T> ref(reference_wrapper<T> original) BSLS_KEYWORD_NOEXCEPT;

} // close namespace bsl

// ============================================================================
// INLINE DEFINITIONS
// ============================================================================

// -----------------------
// class reference_wrapper
// -----------------------

// CREATORS
template <class T>
inline
bsl::reference_wrapper<T>::reference_wrapper(T& object) BSLS_KEYWORD_NOEXCEPT
: d_represented_p(BloombergLP::bsls::Util::addressOf(object))
{
}

// ACCESSORS
template <class T>
inline
T& bsl::reference_wrapper<T>::get() const BSLS_KEYWORD_NOEXCEPT
{
return *d_represented_p;
}

template <class T>
inline
bsl::reference_wrapper<T>::operator T&() const BSLS_KEYWORD_NOEXCEPT
{
return *d_represented_p;
}

// FREE FUNCTIONS
template <class T>
inline
bsl::reference_wrapper<const T> bsl::cref(const T& object)
BSLS_KEYWORD_NOEXCEPT
{
return reference_wrapper<const T>(object);
}

template <class T>
inline
bsl::reference_wrapper<const T> bsl::cref(bsl::reference_wrapper<T> original)
BSLS_KEYWORD_NOEXCEPT
{
return cref(original.get());
}

template <class T>
inline
bsl::reference_wrapper<T> bsl::ref(T& object) BSLS_KEYWORD_NOEXCEPT
{
return reference_wrapper<T>(object);
}

template <class T>
inline
bsl::reference_wrapper<T> bsl::ref(bsl::reference_wrapper<T> original)
BSLS_KEYWORD_NOEXCEPT
{
return ref(original.get());
}

// TRAITS

namespace BloombergLP {
namespace bslmf {

template <class T>
struct IsBitwiseMoveable<bsl::reference_wrapper<T> > : bsl::true_type { };

} // close namespace bslmf
} // close enterprise namespace

#endif // BSLMF_REFERENCEWRAPPER_IS_ALIASED

namespace BloombergLP {
namespace bslmf {

template <class T>
struct IsReferenceWrapper<bsl::reference_wrapper<T> > : bsl::true_type { };

} // close namespace bslmf
} // close enterprise namespace

#endif

// ----------------------------------------------------------------------------
// Copyright 2013 Bloomberg Finance L.P.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------- END-OF-FILE ----------------------------------
Loading

0 comments on commit 5aa9844

Please sign in to comment.