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
case 0: t_T0; t_T0,
case 1: t_T1; t_T1,
case N - 1: T{N - 1}; T{N - 1}
} ::
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 {
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 {
char d_buffer[LEN];
public:
ShortString(const char *s = "") { std::strncpy(d_buffer, s, LEN); }
void retrieve(data_Server *server);
void store(data_Server *server) const;
char operator[](int n) const { return d_buffer[n]; }
};
template <int LEN>
bool operator==(
const ShortString<LEN>& lhs,
const ShortString<LEN>& rhs)
{
return 0 == std::memcmp(&lhs, &rhs, LEN);
}
template <int LEN>
bool operator==(
const ShortString<LEN>& lhs,
const char *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)
{
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
{
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;
}
◆ bslmf_Switch
◆ bslmf_Switch2
◆ bslmf_Switch3
◆ bslmf_Switch4
◆ bslmf_Switch5
◆ bslmf_Switch6
◆ bslmf_Switch7
◆ bslmf_Switch8
◆ bslmf_Switch9