BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlat_valuetypefunctions

Classes

struct  bdlat_ValueTypeFunctions_Imp
 

Functions

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)
 

Detailed Description

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:

Types in the bdlat "value type" framework are required to have:

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:

// MANIPULATORS
template <class RHS_TYPE>
int bdlat_valueTypeAssign(YOUR_TYPE *lhs, const RHS_TYPE& rhs);
// Assign to the specified 'lhs' the value if the specified 'rhs'.
// Return 0 on success and a non-zero value otherwise. If setting
// 'lhs' to 'rhs' would violate any preconditions, a non-zero value is
// returned. If (template parameter) 'RHS_TYPE' cannot be used to set
// the value of 'lhs', a non-zero value is returned.
void bdlat_valueTypeReset(YOUR_TYPE *object);
// Reset the specified 'object' to that of its default state (i.e., to
// 'YOUR_TYPE()').

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 typedefs. For example, see bdlat_arrayfunctions and bdlat_nullablevaluefunctions .

There are two significant implications of the contract for bdlat_valueTypeAssign:

Supported Types

This component provides "value type" support for the following types:

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;
};
} // close package namespace
} // close enterprise namespace

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 }; // aggregate braced initialization
mine::MyValueType b(a); // implicit copy constructor
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; // implicit copy assignment operator
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) { }
YourValueType(const bsl::pair<int, double>& value) // IMPLICIT
: 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;
}
};
} // close package namespace
} // close enterprise namespace
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); // value initialization
your::YourValueType b(a); // implicit copy constructor
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; // implicit copy assignment operator
assert(b.d_int == a.d_int);
assert(b.d_double == a.d_double);
bsl::pair<int, double> value(4, 5.0);
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.

bsl::pair<int, double> value(4, 5.0);
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.

// Assign an incompatible type.
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 {
// DATA
int d_int;
double d_double;
private:
// NOT IMPLEMENTED
TheirValueType(const TheirValueType& original); // = delete
TheirValueType& operator=(const TheirValueType&); // = delete
public:
// CREATORS
TheirValueType()
: d_int()
, d_double() { }
// MANIPULATORS
void setValue(const bsl::string& valueString);
// ACCESSORS
int intValue() const { return d_int; }
double doubleValue() const { return d_double; }
};
// MANIPULATORS
void TheirValueType::setValue(const bsl::string& valueString)
{
bsl::string::size_type pos = valueString.find(',');
d_int = bsl::atoi(valueString.c_str());
d_double = bsl::atof(valueString.c_str() + pos + 1);
}
} // close package namespace
} // close enterprise namespace
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; // default constructor
assert(0 == a. intValue());
assert(0.0 == a.doubleValue());
// their::TheirValueType b(a); // Error, no copy constructor
their::TheirValueType c;
// c = a; // Error, no copy assignment operator
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,
const bsl::string& rhs)
{
lhs->setValue(rhs);
return 0;
}
// Overload for any other 'RHS_TYPE' to return an error.
template <class RHS_TYPE>
int bdlat_valueTypeAssign(TheirValueType *lhs,
const RHS_TYPE& rhs)
{
(void)lhs;
(void)rhs;
return -999; // Pick a distinctive non-negative value.
}
void bdlat_valueTypeReset(TheirValueType *object)
{
BSLS_ASSERT(object);
oss << int() << ", " << double();
object->setValue(oss.str());
}
} // close package namespace
} // close enterprise namespace
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:

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());
// Assign an incompatible type.
bsl::pair<int, double> value(4, 5.0);
assert( 0 != rc);
assert(-999 == rc);
}

Function Documentation

◆ assign() [1/10]

template<class RHS_TYPE >
int bdlat_ValueTypeFunctions_Imp::assign ( bsl::string lhs,
bdlat_TypeCategory::Simple  ,
const RHS_TYPE &  rhs,
bdlat_TypeCategory::Enumeration   
)
static

◆ assign() [2/10]

template<class RHS_TYPE >
int bdlat_ValueTypeFunctions_Imp::assign ( char *  lhs,
bdlat_TypeCategory::Simple  ,
const RHS_TYPE &  rhs,
bdlat_TypeCategory::Enumeration   
)
static

◆ assign() [3/10]

template<class RHS_TYPE >
int bdlat_ValueTypeFunctions_Imp::assign ( int *  lhs,
bdlat_TypeCategory::Simple  ,
const RHS_TYPE &  rhs,
bdlat_TypeCategory::Enumeration   
)
static

◆ assign() [4/10]

template<class LHS_TYPE >
int bdlat_ValueTypeFunctions_Imp::assign ( LHS_TYPE *  lhs,
bdlat_TypeCategory::Enumeration  ,
const bsl::string rhs,
bdlat_TypeCategory::Simple   
)
static

◆ assign() [5/10]

template<class LHS_TYPE >
int bdlat_ValueTypeFunctions_Imp::assign ( LHS_TYPE *  lhs,
bdlat_TypeCategory::Enumeration  ,
const char &  rhs,
bdlat_TypeCategory::Simple   
)
static

◆ assign() [6/10]

template<class LHS_TYPE >
int bdlat_ValueTypeFunctions_Imp::assign ( LHS_TYPE *  lhs,
bdlat_TypeCategory::Enumeration  ,
const int &  rhs,
bdlat_TypeCategory::Simple   
)
static

◆ assign() [7/10]

template<class LHS_TYPE >
int bdlat_ValueTypeFunctions_Imp::assign ( LHS_TYPE *  lhs,
bdlat_TypeCategory::Enumeration  ,
const short &  rhs,
bdlat_TypeCategory::Simple   
)
static

◆ assign() [8/10]

template<class LHS_TYPE , class RHS_TYPE >
int bdlat_ValueTypeFunctions_Imp::assign ( LHS_TYPE *  lhs,
bdlat_TypeCategory::Simple  ,
const RHS_TYPE &  rhs,
bdlat_TypeCategory::Simple   
)
static

◆ 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 >
int bdlat_ValueTypeFunctions_Imp::assign ( short *  lhs,
bdlat_TypeCategory::Simple  ,
const RHS_TYPE &  rhs,
bdlat_TypeCategory::Enumeration   
)
static

◆ 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]

template<class TYPE >
void bdlat_ValueTypeFunctions_Imp::reset ( bdlb::NullableValue< TYPE > *  object)
inlinestatic

◆ 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