|
template<class LHS_TYPE > |
static int | bdlat_ValueTypeFunctions_Imp::assign (LHS_TYPE *lhs, bdlat_TypeCategory::Enumeration, const char &rhs, bdlat_TypeCategory::Simple) |
|
template<class LHS_TYPE > |
static int | bdlat_ValueTypeFunctions_Imp::assign (LHS_TYPE *lhs, bdlat_TypeCategory::Enumeration, const short &rhs, bdlat_TypeCategory::Simple) |
|
template<class LHS_TYPE > |
static int | bdlat_ValueTypeFunctions_Imp::assign (LHS_TYPE *lhs, bdlat_TypeCategory::Enumeration, const int &rhs, bdlat_TypeCategory::Simple) |
|
template<class LHS_TYPE > |
static int | bdlat_ValueTypeFunctions_Imp::assign (LHS_TYPE *lhs, bdlat_TypeCategory::Enumeration, const bsl::string &rhs, bdlat_TypeCategory::Simple) |
|
template<class RHS_TYPE > |
static int | bdlat_ValueTypeFunctions_Imp::assign (char *lhs, bdlat_TypeCategory::Simple, const RHS_TYPE &rhs, bdlat_TypeCategory::Enumeration) |
|
template<class RHS_TYPE > |
static int | bdlat_ValueTypeFunctions_Imp::assign (short *lhs, bdlat_TypeCategory::Simple, const RHS_TYPE &rhs, bdlat_TypeCategory::Enumeration) |
|
template<class RHS_TYPE > |
static int | bdlat_ValueTypeFunctions_Imp::assign (int *lhs, bdlat_TypeCategory::Simple, const RHS_TYPE &rhs, bdlat_TypeCategory::Enumeration) |
|
template<class RHS_TYPE > |
static int | bdlat_ValueTypeFunctions_Imp::assign (bsl::string *lhs, bdlat_TypeCategory::Simple, const RHS_TYPE &rhs, bdlat_TypeCategory::Enumeration) |
|
template<class LHS_TYPE , class RHS_TYPE > |
static int | bdlat_ValueTypeFunctions_Imp::assign (LHS_TYPE *lhs, bdlat_TypeCategory::Simple, const RHS_TYPE &rhs, bdlat_TypeCategory::Simple) |
|
template<class LHS_TYPE , class LHS_CATEGORY , class RHS_TYPE , class RHS_CATEGORY > |
static int | bdlat_ValueTypeFunctions_Imp::assign (LHS_TYPE *lhs, LHS_CATEGORY, const RHS_TYPE &rhs, RHS_CATEGORY) |
|
template<class LHS_TYPE , class RHS_TYPE > |
static int | bdlat_ValueTypeFunctions_Imp::assignSimpleTypes (LHS_TYPE *lhs, const RHS_TYPE &rhs, IsConvertible) |
|
template<class LHS_TYPE , class RHS_TYPE > |
static int | bdlat_ValueTypeFunctions_Imp::assignSimpleTypes (LHS_TYPE *lhs, const RHS_TYPE &rhs, IsNotConvertible) |
|
template<class TYPE > |
static void | bdlat_ValueTypeFunctions_Imp::reset (TYPE *object) |
|
template<class TYPE > |
static void | bdlat_ValueTypeFunctions_Imp::reset (bdlb::NullableValue< TYPE > *object) |
|
template<class TYPE , class ALLOC > |
static void | bdlat_ValueTypeFunctions_Imp::reset (bsl::vector< TYPE, ALLOC > *object) |
|
template<class CHAR_T , class CHAR_TRAITS , class ALLOC > |
static void | bdlat_ValueTypeFunctions_Imp::reset (bsl::basic_string< CHAR_T, CHAR_TRAITS, ALLOC > *object) |
|
template<class TYPE > |
static void | bdlat_ValueTypeFunctions_Imp::reset (TYPE *object, UseResetMethod) |
|
template<class TYPE > |
static void | bdlat_ValueTypeFunctions_Imp::reset (TYPE *object, UseDefaultCtor) |
|
Outline
Purpose
Provide a namespace for "value type" functions.
Classes
Description
This component provides a namespace
, bdlat_ValueTypeFunctions
, defining functions that may be called on "value
types".
The functions in this namespace allow users to:
assign
values to "value type" objects (ie., as if by using the assignment operator *lhs = rhs
), and
reset
"value type" objects to their default state (i.e., as if each object was just constructed using its default constructor).
Types in the bdlat
"value type" framework are required to have:
- a default constructor
- a copy assignment operator
- the free function template and the free function described below.
Types in the bdlat
"value type" framework must define in the namespace where the type is defined, overloads of the following free function template and free frunction. Note that the placeholder YOUR_TYPE
is not a template argument and should be replaced with the name of the type being plugged into the framework:
template <class RHS_TYPE>
int bdlat_valueTypeAssign(YOUR_TYPE *lhs, const RHS_TYPE& rhs);
void bdlat_valueTypeReset(YOUR_TYPE *object);
Notice that, unlike other bdlat
type infrastructures, the bdlat
"value" infrastructure does not require the setting of any traits, or definition of meta-functions, or creation of any typedef
s. For example, see bdlat_arrayfunctions and bdlat_nullablevaluefunctions .
There are two significant implications of the contract for bdlat_valueTypeAssign
:
- Interactions with incompatible types are handled at run-time, not compile-time.
- Users of the
bdlat_valueTypeAssign
function deal with a wide contract, even if the corresponding operation in YOUR_TYPE
has a narrow contract.
Supported Types
This component provides "value type" support for the following types:
- All types with a default constructor and copy assignment operator.
- Types having any of the following traits (see bdlat_typetraits ):
Usage
This section illustrates intended use of this component.
Example 1: Implicit "Value Type"
Suppose you had a type that defines a "value".
namespace BloombergLP {
namespace mine {
struct MyValueType {
int d_int;
double d_double;
};
}
}
Although our definition of MyValueType
was rather terse, several methods are implicitly defined by the compiler:
void f()
{
using namespace BloombergLP;
mine::MyValueType a = { 1, 1.0 };
mine::MyValueType b(a);
assert(b.d_int == a.d_int);
assert(b.d_double == a.d_double);
a.d_int = 2;
a.d_double = 3.14;
b = a;
assert(b.d_int == a.d_int);
assert(b.d_double == a.d_double);
}
Notice that the implicitly defined methods include a copy constructor and a copy assignment operator thereby implicitly making MyValueType
part of the bdlat
"value" framework. As such, it can be manipulated using the methods of bdlat_ValueTypeFunctions
:
void myUsageScenario()
{
using namespace BloombergLP;
mine::MyValueType x = { 7, 10.0 };
mine::MyValueType y = { 99, -1.0 };
assert(x.d_int != y.d_int);
assert(x.d_double != y.d_double);
assert(0 == rc);
assert(x.d_int == y.d_int);
assert(x.d_double == y.d_double);
assert(x.d_int != y.d_int);
assert(x.d_double != y.d_double);
assert(int() == y.d_int);
assert(double() == y.d_double);
}
void reset(TYPE *object)
Reset the value of the specified object to its default value.
int assign(LHS_TYPE *lhs, const RHS_TYPE &rhs)
Example 2: Interacting with Other Types
Suppose you want to enhance mine::MyValueType
to allow its value to be assigned from a bsl::pair<int, float>
object? Do do so, create your::YourValueType
which has an implicit conversion from bsl::pair<int, float>
:
namespace BloombergLP {
namespace your {
struct YourValueType {
int d_int;
double d_double;
YourValueType()
: d_int()
, d_double() { }
YourValueType(const YourValueType& original)
: d_int (original.d_int)
, d_double(original.d_double) { }
YourValueType(int intValue, double doubleValue)
: d_int ( intValue)
, d_double(doubleValue) { }
: d_int (value.first)
, d_double(value.second) { }
YourValueType & operator=(const YourValueType& original) {
d_int = original.d_int;
d_double = original.d_double;
return *this;
}
};
}
}
Definition bslstl_pair.h:1210
Notice that, having defined a constructor, the compiler no longer generates the constructors that had been generated implicitly. Accordingly, we have added a default constructor, copy constructor and assignment operator. Also, since aggregate initialization is no longer allowed, we have also added a value constructor and slightly modified the syntax of initialization in function g()
below:
void g()
{
using namespace BloombergLP;
your::YourValueType a(1, 1.0);
your::YourValueType b(a);
assert(b.d_int == a.d_int);
assert(b.d_double == a.d_double);
a.d_int = 2;
a.d_double = 3.14;
b = a;
assert(b.d_int == a.d_int);
assert(b.d_double == a.d_double);
a = value;
assert(4 == a.d_int);
assert(5.0 == a.d_double);
}
Since both copy construction and assignment are defined, YourValueType
can be handled by the bdlat
"value" infrastructure in much the same way as we did for MyValueType
:
void yourUsageScenario()
{
using namespace BloombergLP;
int rc;
your::YourValueType x( 7, 10.0);
your::YourValueType y(99, -1.0);
assert(x.d_int != y.d_int);
assert(x.d_double != y.d_double);
assert(0 == rc);
assert(x.d_int == y.d_int);
assert(x.d_double == y.d_double);
assert(x.d_int != y.d_int);
assert(x.d_double != y.d_double);
assert(int() == y.d_int);
assert(float() == y.d_double);
However, since conversion from another type, bsl::pair<int, double>
, is provided, the bdlat
"value" infrastructure can also use that type to set the value of objects.
assert(0 == rc);
assert(value.first == y.d_int);
assert(value.second == y.d_double);
Unsurprisingly, such assignments do not work for arbitrary other types (for which conversion is not defined). What is notable, is that this code does compile and fails at run-time.
assert(0 != rc);
}
Definition bslstl_string.h:1281
Installing an Atypical "Value" Type
Suppose someone defines a pernicious "value" type, their::TheirValueType
, having neither copy constructor nor copy assignment operator:
namespace BloombergLP {
namespace their {
class TheirValueType {
int d_int;
double d_double;
private:
TheirValueType(const TheirValueType& original);
TheirValueType& operator=(const TheirValueType&);
public:
TheirValueType()
: d_int()
, d_double() { }
int intValue() const { return d_int; }
double doubleValue() const { return d_double; }
};
void TheirValueType::setValue(
const bsl::string& valueString)
{
d_int = bsl::atoi(valueString.
c_str());
d_double = bsl::atof(valueString.
c_str() + pos + 1);
}
}
}
const CHAR_TYPE * c_str() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_string.h:6705
AllocatorTraits::size_type size_type
Definition bslstl_string.h:1303
size_type find(const basic_string &substring, size_type position=0) const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_string.h:6732
static const size_type npos
Definition bslstl_string.h:1676
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
Such a type can be used after a fashion (objects created, states changed, state changes observed), albeit using syntax that is significantly different than we used for MyValueType
and YourValueType
:
void h()
{
using namespace BloombergLP;
their::TheirValueType a;
assert(0 == a. intValue());
assert(0.0 == a.doubleValue());
their::TheirValueType c;
a.setValue("2, 3.14");
assert(2 == a. intValue());
assert(3.14 == a.doubleValue());
}
Since TheirValueType
lacks both copy construction and assignment, that type is not implicitly supported by the bdlat
"value" infrastructure.
However, the TheirValueType
can be made compatible with that infrastructure if "they" define the required overloads of bdlat_valueTypeAssign
and bdlat_valueTypeReset
in their
namespace:
namespace BloombergLP {
namespace their {
int bdlat_valueTypeAssign(TheirValueType *lhs,
const TheirValueType& rhs)
{
oss << rhs.intValue() << ", " << rhs.doubleValue();
lhs->setValue(oss.
str());
return 0;
}
int bdlat_valueTypeAssign(TheirValueType *lhs,
{
lhs->setValue(rhs);
return 0;
}
template <class RHS_TYPE>
const RHS_TYPE& rhs)
{
(void)lhs;
(void)rhs;
return -999;
}
{
oss << int() << ", " << double();
object->setValue(oss.
str());
}
}
}
Definition bslstl_ostringstream.h:175
void str(const StringType &value)
Definition bslstl_ostringstream.h:581
void bdlat_valueTypeReset(TYPE *object)
int bdlat_valueTypeAssign(LHS_TYPE *lhs, const RHS_TYPE &rhs)
Notice that three overloads of bdlat_valueTypeAssign
are defined above:
- The first, the overload that allows
TheirValueType
to be "assigned" to itself is required by the bdlat
"value" infrastructure.
- The second, the overload that allows "assignment" from a
bsl::string
is not technically required by the infrastructure, but is a practical requirement because bsl::string
is the only way TheirValueType
can be changed from its default value.
- Finally, we provide an overload templated on an arbitrary
RHS_TYPE
so that, if any other types are passed, the code will compile (as required) but also unconditionally fail (as required).
With these points of customization in place, TheirValueType
can now be manipulated by the bdlat
"value" infrastructure in much the same manner as was done for MyValueType
and YourValueType
:
void theirUsageScenario()
{
using namespace BloombergLP;
their::TheirValueType x;
their::TheirValueType y;
int rc;
assert(0 == rc);
assert(0 == rc);
assert(x.intValue() != y.intValue());
assert(x.doubleValue() != y.doubleValue());
assert(0 == rc);
assert(x.intValue() == y.intValue());
assert(x.doubleValue() == y.doubleValue());
assert(int() == y.intValue());
assert(float() == y.doubleValue());
assert( 0 != rc);
assert(-999 == rc);
}
◆ assign() [1/10]
template<class RHS_TYPE >
◆ assign() [2/10]
template<class RHS_TYPE >
◆ assign() [3/10]
template<class RHS_TYPE >
◆ assign() [4/10]
template<class LHS_TYPE >
◆ assign() [5/10]
template<class LHS_TYPE >
◆ assign() [6/10]
template<class LHS_TYPE >
◆ assign() [7/10]
template<class LHS_TYPE >
◆ assign() [8/10]
template<class LHS_TYPE , class RHS_TYPE >
◆ assign() [9/10]
template<class LHS_TYPE , class LHS_CATEGORY , class RHS_TYPE , class RHS_CATEGORY >
int bdlat_ValueTypeFunctions_Imp::assign |
( |
LHS_TYPE * |
lhs, |
|
|
LHS_CATEGORY |
, |
|
|
const RHS_TYPE & |
rhs, |
|
|
RHS_CATEGORY |
|
|
) |
| |
|
static |
◆ assign() [10/10]
template<class RHS_TYPE >
◆ assignSimpleTypes() [1/2]
template<class LHS_TYPE , class RHS_TYPE >
int bdlat_ValueTypeFunctions_Imp::assignSimpleTypes |
( |
LHS_TYPE * |
lhs, |
|
|
const RHS_TYPE & |
rhs, |
|
|
IsConvertible |
|
|
) |
| |
|
inlinestatic |
◆ assignSimpleTypes() [2/2]
template<class LHS_TYPE , class RHS_TYPE >
int bdlat_ValueTypeFunctions_Imp::assignSimpleTypes |
( |
LHS_TYPE * |
lhs, |
|
|
const RHS_TYPE & |
rhs, |
|
|
IsNotConvertible |
|
|
) |
| |
|
inlinestatic |
◆ reset() [1/6]
◆ reset() [2/6]
template<class CHAR_T , class CHAR_TRAITS , class ALLOC >
void bdlat_ValueTypeFunctions_Imp::reset |
( |
bsl::basic_string< CHAR_T, CHAR_TRAITS, ALLOC > * |
object | ) |
|
|
inlinestatic |
◆ reset() [3/6]
template<class TYPE , class ALLOC >
void bdlat_ValueTypeFunctions_Imp::reset |
( |
bsl::vector< TYPE, ALLOC > * |
object | ) |
|
|
inlinestatic |
◆ reset() [4/6]
template<class TYPE >
void bdlat_ValueTypeFunctions_Imp::reset |
( |
TYPE * |
object | ) |
|
|
inlinestatic |
◆ reset() [5/6]
template<class TYPE >
void bdlat_ValueTypeFunctions_Imp::reset |
( |
TYPE * |
object, |
|
|
UseDefaultCtor |
|
|
) |
| |
|
inlinestatic |
◆ reset() [6/6]
template<class TYPE >
void bdlat_ValueTypeFunctions_Imp::reset |
( |
TYPE * |
object, |
|
|
UseResetMethod |
|
|
) |
| |
|
inlinestatic |