BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslmf_containercompatiblerange

Provide a concept for the Standard container-compatible-range.

Outline

Purpose

Provide a concept for the Standard container-compatible-range.

Classes

See also

Description

This component provides a concept, bslmf::ContainerCompatibleRange, that specifies the requirements for range-types used to create/set containers. This is a concrete concept corresponding the Standard, exposition-only, concept container-compatible-range.

Usage

This section illustrates intended use of this component.

Example 1: Declaring a Range Compatible Interface

Suppose we have a container class that we want to be able to accept content from a range. We can use bslmf::ContainerCompatibleRange concept to constrain the relevant templates, removing them from the overload set unless the (template argument) t_RANGE meets the required constraints.

// =================
// class MyContainer
// =================
template <class t_TYPE>
class MyContainer {
public:
// CREATORS
// ...
template <bslmf::ContainerCompatibleRange<t_TYPE> t_RANGE>
MyContainer(bsl::from_range_t , t_RANGE&& range);
// ...
// MANIPULATORS
// ...
template <bslmf::ContainerCompatibleRange<t_TYPE> t_RANGE>
MyContainer& append_range(t_RANGE&& range);
// ...
};
Definition bslstl_ranges.h:301

Notice that the (singular) tag value bsl::from_range is used to clearly direct overload resolution to the range constructor when that is the intent. For other methods, we have the option to incorporate "range" into the method name to avoid ambiguous overloads – i.e., append_range is clearly different from assorted overloads of append (not shown).

Finally, notice that the constraint on t_RANGE and t_TYPE must be repeated in the method definitions:

// -----------------
// class MyContainer
// -----------------
// CREATORS
// ...
template <class t_TYPE>
template <bslmf::ContainerCompatibleRange<t_TYPE> t_RANGE>
MyContainer<t_TYPE>::MyContainer(bsl::from_range_t , t_RANGE&& range)
{
// ...
}
// MANIPULATORS
// ...
template <class t_TYPE>
template <bslmf::ContainerCompatibleRange<t_TYPE> t_RANGE>
MyContainer<t_TYPE>& MyContainer<t_TYPE>::append_range(t_RANGE&& range)
{
// ...
return *this;
}
int main()
{
int intArray[] = { 7, 13 };
MyContainer<int> mc(bsl::from_range, intArray);
// OK, `intArray` is a range.
std::vector<int> iVector = { 42, 666 };
mc.append_range(iVector); // OK, `iVector` is also a range.
std::vector<double> dVector = { 1.0, 32.2, 211.95 };
mc.append_range(dVector); // OK, `dVector` is also a range *and*
// `double` is convertible to `int`.
std::vector<std::string> sVector = { "Tom", "Dick", "Harry" };
mc.append_range(sVector); // Error, `sVector` is a range but
// `bsl::string` is *not* implicitly
// convertible to `int`.
int intValue = -1;
mc.append_range(intValue); // Error, `intValue` has expected type
// *but* is not a range.
return 0;
}
const from_range_t from_range