Working with primitive types

Storing strings

To store simple primitive types such as int, long, double, and so forth, an additional type parameter for the container class templates is needed. For example, to store an int in a db_vector, use this container class:

db_vector<int, ElementHolder<int> >;

To map integers to doubles, use this:

db_map<int, double, ElementHolder<double> >;

To store a char* string with long keys, use this:

db_map<long, char*, ElementHolder<char*> >;

Use this for const char* strings:

db_map<long, const char*, ElementHolder<const char*> >;

To map one const string to another, use this type:

db_map<const char*, const char*, ElementHolder<const char*> >;

The TestVector::test_primitive() method demonstrates more of these examples. You can find this method implemented in the dbstl test suite.

Storing strings

For char* and wchar_t* strings, _DB_STL_StoreElement() must be called following partial or total modifications before iterator movement, container::operator[] or iterator::operator*/-> calls. Without the _DB_STL_StoreElement() call, the modified change will be lost. If storing an new value like this:

*iterator = new_char_star_string;

the call to _DB_STL_StoreElement() is not needed.

Note that passing a NULL pointer to a container of char* type or passing a std::string with no contents at all will insert an empty string of zero length into the database.

The string returned from a container will not live beyond the next iterator movement call, container::operator[] or iterator::operator*/-> call.

A db_map::value_type::second_type or db_map::datatype_wrap should be used to hold a reference to a container::operator[] return value. Then the reference should be used for repeated references to that value. The *iterator is of type ElementHolder<char *>, which can be automatically converted to a char * pointer using its type conversion operator. Wherever an auto conversion is done by the compiler, the conversion operator of ElementHolder<T> is called. This avoids almost all explicit conversions, except for two use cases:

  1. The *iterator is used as a "..." parameter like this:

    printf("this is the special case %s", *iterator);

    This compiles but causes errors. Instead, an explicit cast should be used:

    printf("this is the special case %s", (char *)*iterator);
  2. For some old compilers, such as gcc3.4.6, the *iterator cannot be used with the ternary ? operator, like this:

    expr ? *iterator : var

    Even when var is the same type as the iterator's value_type, the compiler fails to perform an auto conversion.

When using std::string or std::wstring as the data type for dbstl containers — that is, db_vector<string>, and db_map<string, wstring> — the string's content rather than the string object itself is stored in order to maintain persistence.

You can find example code demonstrating string storage in the TestAssoc::test_char_star_string_storage() and TestAssoc::test_storing_std_strings() methods. These are available in the dbstl test suite.