EXT C++ Library - string_abstraction

By string_abstraction we mostly refer to use of ext::string_abstraction_interface from which the ext::string_abstraction template (and all its specializations) is derived. This simple facility allows their users to postpone a resolution whether the string is of wide-characters or not from initialization to its actual use.


Interface:

struct ext::string_abstraction_interface {
    public:
        virtual bool         is_wide () const = 0;
        virtual std::string  to_string () const = 0;
        virtual std::wstring to_wstring () const = 0;

    public:
        virtual ~string_abstraction_interface () throw ();
};

template <typename T>
struct ext::string_abstraction : public ext::string_abstraction_interface {
    public:
        typedef T underlying_type;

    public:
        string_abstraction (const std::basic_string <T> &);
        virtual ~string_abstraction () throw ();

        virtual bool         is_wide () const;
        virtual std::string  to_string () const;
        virtual std::wstring to_wstring () const;
};

namespace ext {
template <typename T>
string_abstraction_interface * abstract_string (const std::basic_string <T> &)
string_abstraction_interface * abstract_string (const char *);
string_abstraction_interface * abstract_string (const wchar_t *);
};

Details:

A pointer to ext::string_abstraction_interface is used wherever the string abstraction is needed. Then, when the string is finally available (mostly passed by a function template), an actual ext::string_abstraction is new-allocated and assigned to the appropriate ext::string_abstraction_interface pointer.

The ext::abstract_string function (a set of overloaded functions) is available to simplify the actual initialization of the ext::string_abstraction_interface pointer.

Examples:

#include <ext/c++>

class C {
    private:
        ext::string_abstraction_interface * name;
        ext::string_abstraction_interface * param;

    public:
        template <typename T, typename U>
        C (const std::basic_string <T> & _name,
           const std::basic_string <U> & _param)
            :   name (ext::abstract_string (_name)),
                param (ext::abstract_string (_param)) {};

        C (const char * _name, const char * _param)
            :   name (ext::abstract_string (_name)),
                param (ext::abstract_string (_param)) {};
        C (const wchar_t * _name, const wchar_t * _param)
            :   name (ext::abstract_string (_name)),
                param (ext::abstract_string (_param)) {};
        C (const wchar_t * _name, const char * _param)
            :   name (ext::abstract_string (_name)),
                param (ext::abstract_string (_param)) {};
        C (const char * _name, const wchar_t * _param)
            :   name (ext::abstract_string (_name)),
                param (ext::abstract_string (_param)) {};

        ~C () {
            delete this->name;
            delete this->param;
        };

        void operator () () {
            // postponed resolution
            if (this->name->is_wide () || this->param->is_wide ())
                SomeApiFunctionW (this->name->to_wstring ().c_str (),
                                  this->param->to_wstring ().c_str ());
            else
                SomeApiFunctionA (this->name->to_string ().c_str (),
                                  this->param->to_string ().c_str ());
        };
    };

See first remark for details to this example.

Remarks

The ext::string_abstraction_interface is successfully used when abstracting away the duality of Windows API functions (A/W variants) where the A-variant is called when neither argument is a wide-character string and W-variant otherwise. This allows a single middle-ware class to be used on Windows 9x/Me (these does not support those W-variants) and still support Unicode (wide-characters) in projects where neccessary at the same time.


[index]