XB Library: xb::compact

The xb::compact template function tries to convert the provided data of certain type into equivalent type with smaller footprint (size) without loss of information.


namespace xb {
    template <typename T>
    xb::element compact (const T & v);

Default implementation simply passes v to the xb::element constructor and returns the element. Overloaded versions are provided for following data types:

When converting longer numeric types to shorter, the most compact correct type is used. For example: 1ull is converted to unsigned byte thus saving 5 bytes, and 1.0l is converted to 1.0f which saves 6 bytes.

An overloaded version of xb::compact is required for all data types that should be assignable to xb::node as a value, thus effectively intializing the xb::value class by the data type.

User specialization:

Overload the xb::compact function if you have implemented two (or more) data types where one can be, in certain cases, converted to the other one, which has smaller footprint, and you want this conversion to be done automaticaly whenever possible.


#include <xb/xb_compact.hpp>

// ...

class myTypeLong { /* ... */ };
class myTypeShort { /* ... */ };

// ...

namespace xb {
    xb::element compact (const myTypeLong & v) {
        if (myTypeLong (myTypeShort (v)) == v)
            return xb::element (myTypeShort (v));
            return xb::element (v);

// ...

Note that this example suffers from poor performance as the v is converted to myTypeShort unneccessaryly twice. In more complex types you wouldn't probably rely on checking if conversion to and back yields in the same data but you would provide a routine to check for possibility of such lossless conversion.


Note that you will also need to specialize the xb::extend template to be able to correctly retrieve the types from XB values.