mirror of
https://github.com/boostorg/convert.git
synced 2026-02-17 13:42:18 +00:00
70 lines
2.9 KiB
Plaintext
70 lines
2.9 KiB
Plaintext
[section Type Requirements]
|
|
|
|
In order for a user-defined type to be integrated into the ['boost::lexical_cast] framework:
|
|
|
|
* TypeOut needs to be ['Copy Constructible];
|
|
* TypeOut needs to be ['Default Constructible];
|
|
* TypeOut needs to be ['Input Streamable];
|
|
* TypeIn needs to be ['Output Streamable].
|
|
|
|
The first two requirements imposed are by the ['boost::lexical_cast] design and implementation and the last two requirements by the underlying ['std::stringstream] engine.
|
|
|
|
In turn, the ['Boost.Convert] API facade requires the type to be
|
|
|
|
* TypeOut needs to be ['Copy Constructible];
|
|
* TypeOut needs to be ['Default Constructible] by default.
|
|
|
|
Additional requirements might be imposed by the respective converter. For example, both mentioned -- ['boost::lexical_cast]-based and ['std::stringstream]-based -- converters require
|
|
|
|
* TypeIn to be ['Output Streamable];
|
|
* TypeOut to be ['Input Streamable].
|
|
|
|
[endsect]
|
|
[section The ['Default Constructible] Type Requirement]
|
|
|
|
Deeply in the bowels of the implementation a temporary-storage instance of the ['TypeOut] type is created and then populated with the conversion result. The ['boost::lexical_cast] implementation chooses the default constructor to create such an instance. Consequently, the ['TypeOut] type needs to be ['Default Constructible]. For more details see __ref_1__.
|
|
|
|
['Boost.Convert also creates a temporary-storage instance of the ['TypeOut] type that the respective converter then populates with the conversion result. By default that temporary-storage is created with
|
|
|
|
namespace boost
|
|
{
|
|
template<class TypeOut>
|
|
TypeOut
|
|
convert<TypeOut>::create_storage()
|
|
{
|
|
return TypeOut();
|
|
}
|
|
}
|
|
|
|
and, therefore, the ['Default Constructible] requirement is also the ['default] requirement of the ['Boost.Convert] framework.
|
|
|
|
A well-designed type (in my opinion, anyway) should only have meaningful and unambiguous constructors... and the default constructor is not always and necessarily one of them. Consider the following ['direction] type as one such example. The type has only two meaningful states and is not ['Default Constructible]:
|
|
|
|
struct direction
|
|
{
|
|
enum value_type { up, dn };
|
|
direction(value_type value) : value_(value) {}
|
|
private: value_type value_;
|
|
};
|
|
|
|
For such a type the call below will not compile (due to the ['Default Constructible] requirement):
|
|
|
|
direction dir1 = lexical_cast<direction>(str); // Does not compile
|
|
direction dir2 = convert<direction>::from(str).value(); // Does not compile
|
|
|
|
However, ['Boost.Convert] is able to handle such a type with little help from the user. What is needed is the instructions ['how] to create that mentioned temporary-storage:
|
|
|
|
namespace boost
|
|
{
|
|
template<> inline direction convert<direction>::create_storage()
|
|
{
|
|
return direction(direction::up);
|
|
}
|
|
}
|
|
|
|
Now the conversion code compiles:
|
|
|
|
direction dir2 = convert<direction>::from(str).value(); // Compiles
|
|
|
|
[endsect]
|