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

Macros

#define bslmf_Switch   bslmf::Switch
 This alias is defined for backward compatibility.
 
#define bslmf_Switch2   bslmf::Switch2
 This alias is defined for backward compatibility.
 
#define bslmf_Switch3   bslmf::Switch3
 This alias is defined for backward compatibility.
 
#define bslmf_Switch4   bslmf::Switch4
 This alias is defined for backward compatibility.
 
#define bslmf_Switch5   bslmf::Switch5
 This alias is defined for backward compatibility.
 
#define bslmf_Switch6   bslmf::Switch6
 This alias is defined for backward compatibility.
 
#define bslmf_Switch7   bslmf::Switch7
 This alias is defined for backward compatibility.
 
#define bslmf_Switch8   bslmf::Switch8
 This alias is defined for backward compatibility.
 
#define bslmf_Switch9   bslmf::Switch9
 This alias is defined for backward compatibility.
 

Detailed Description

Outline

Purpose

Provide a compile-time switch meta-function.

Classes

See also
bslmf_typelist

Description

This component provides a compile-time switch meta-function. Its main class, bslmf::Switch, parameterized by an integral t_SWITCH_SELECTOR and a variable number N of types, t_T0 up to T{N - 1}, contains a single type named Type, which is the result of the meta-function and is an alias to T{t_SWITCH_SELECTOR} or to bslmf::Nil if t_SWITCH_SELECTOR is outside the range [ 0 .. N - 1 ]. The analogy between the following "meta-code" and its valid C++ version using bslmf::Switch may serve as a useful mental picture to understand and memorize the usage of this component.

"Meta-code" (not C++) Valid C++ using 'bslmf::Switch'
--------------------- ------------------------------
typedef typedef typename
switch (t_SWITCH_SELECTOR) { bslmf::Switch<t_SWITCH_SELECTOR,
case 0: t_T0; t_T0,
case 1: t_T1; t_T1,
// . . . // . . .
case N - 1: T{N - 1}; T{N - 1}
default: bslmf::Nil; >
} ::
Type; Type;
This struct is empty and represents a nil type.
Definition bslmf_nil.h:131
Definition bslmf_switch.h:537

Note the use of the keyword typename, necessary only if one or more of the t_SWITCH_SELECTOR or t_T0 up to T{N - 1} is dependent on a template parameter of the local context (i.e., that of the block using bslmf::Switch). In particular, it should be omitted if the bslmf::Switch is not used within a class or function template, as in the usage example below.

For most situations, the number N of template type arguments is known and the bslmf::SwitchN meta-functions, which take exactly the indicated number of arguments, should be preferred. Their usage leads to shorter mangled symbol names in object files (e.g., no extra defaulted template type arguments are included in the name), and shorter compilation times, as well.

Usage

Assume an external server API for storing and retrieving data:

class data_Server {
// Dummy implementation of data server
int d_data;
public:
void store(char data) { d_data = data | 0Xefface00; }
void store(short data) { d_data = data | 0Xdead0000; }
void store(int data) { d_data = data; }
void retrieve(char *data) {
*data = static_cast<char>(d_data & 0x000000ff);
}
void retrieve(short *data) {
*data = static_cast<short>(d_data & 0x0000ffff);
}
void retrieve(int *data) { *data = d_data; }
};
BSLS_KEYWORD_CONSTEXPR CONTAINER::value_type * data(CONTAINER &container)
Definition bslstl_iterator.h:1231

In our application, we need some very small (1, 2, and 4-byte), special-purpose string types, so we create the following ShortString class template:

template <int LEN>
class ShortString {
// Store a short, fixed-length string.
char d_buffer[LEN];
public:
ShortString(const char *s = "") { std::strncpy(d_buffer, s, LEN); }
// Construct a 'ShortString' from a NTCS.
void retrieve(data_Server *server);
// Retrieve this string from a data server.
void store(data_Server *server) const;
// Store this string to a data server.
char operator[](int n) const { return d_buffer[n]; }
// Return the nth byte in this string.
};
template <int LEN>
bool operator==(const ShortString<LEN>& lhs, const ShortString<LEN>& rhs)
// Return true if a 'lhs' is equal to 'rhs'
{
return 0 == std::memcmp(&lhs, &rhs, LEN);
}
template <int LEN>
bool operator==(const ShortString<LEN>& lhs, const char *rhs)
// Return true if a 'ShortString' 'lhs' is equal to a NTCS 'rhs'.
{
int i;
for (i = 0; LEN > i && lhs[i]; ++i) {
if (lhs[i] != rhs[i]) {
return false;
}
}
return ('\0' == rhs[i]);
}
bool operator==(const FileCleanerConfiguration &lhs, const FileCleanerConfiguration &rhs)

We would like to store our short strings in the data server, but the data server only handles char, short and int types. Since our strings fit into these simple types, we can transform ShortString into these integral types when calling store and retrieve, using bslmf::Switch to choose which integral type to use for each ShortString type:

template <int LEN>
void ShortString<LEN>::retrieve(data_Server *server)
{
// 'transferType will be 'char' if 'LEN' is 1, 'short' if 'LEN' is 2,
// and 'int' if 'LEN' 4. Will choose 'void' and thus not compile if
// 'LEN' is 0 or 3.
typedef typename
transferType x = 0;
server->retrieve(&x);
std::memcpy(d_buffer, &x, LEN);
}
template <int LEN>
void ShortString<LEN>::store(data_Server *server) const
{
// 'transferType will be 'char' if 'LEN' is 1, 'short' if 'LEN' is 2,
// and 'int' if 'LEN' 4. Will choose 'void' and thus not compile if
// 'LEN' is 0 or 3.
typedef typename
transferType x = 0;
std::memcpy(&x, d_buffer, LEN);
server->store(x);
}

In our main program, we first assert our basic assumptions, then we store and retrieve strings using our ShortString template.

int main()
{
assert(2 == sizeof(short));
assert(4 == sizeof(int));
data_Server server;
ShortString<1> a("A");
ShortString<1> b("B");
assert(a == "A");
assert(b == "B");
assert(! (a == b));
a.store(&server);
b.retrieve(&server);
assert(a == "A");
assert(b == "A");
assert(a == b);
ShortString<2> cd("CD");
ShortString<2> ef("EF");
assert(cd == "CD");
assert(ef == "EF");
assert(! (cd == ef));
cd.store(&server);
ef.retrieve(&server);
assert(cd == "CD");
assert(ef == "CD");
assert(cd == ef);
ShortString<4> ghij("GHIJ");
ShortString<4> klmn("KLMN");
assert(ghij == "GHIJ");
assert(klmn == "KLMN");
assert(! (ghij == klmn));
ghij.store(&server);
klmn.retrieve(&server);
assert(ghij == "GHIJ");
assert(klmn == "GHIJ");
assert(ghij == klmn);
return 0;
}

Macro Definition Documentation

◆ bslmf_Switch

#define bslmf_Switch   bslmf::Switch

◆ bslmf_Switch2

#define bslmf_Switch2   bslmf::Switch2

◆ bslmf_Switch3

#define bslmf_Switch3   bslmf::Switch3

◆ bslmf_Switch4

#define bslmf_Switch4   bslmf::Switch4

◆ bslmf_Switch5

#define bslmf_Switch5   bslmf::Switch5

◆ bslmf_Switch6

#define bslmf_Switch6   bslmf::Switch6

◆ bslmf_Switch7

#define bslmf_Switch7   bslmf::Switch7

◆ bslmf_Switch8

#define bslmf_Switch8   bslmf::Switch8

◆ bslmf_Switch9

#define bslmf_Switch9   bslmf::Switch9