Perbert
Perbert

Reputation: 595

How to handle a value that may be an std::string or std::wstring

I have some code that reads a file and finds out whether it's Unicode or not. Depending on this I'd like to have a custom object that will hold the file contents as wstring or string and be able to do string manipulation.

I thought I could just have a base class with two derived classes representing wide and narrow strings or even a base class for string and one derived for wstring. Something like:

class CustomString
{
public:
   static CustomString *methodFactory(bool _unicode);
   std::string Value;

}

class NarrowString : public CustomString
{
public:
   SingleByte(std::string _value);
   std::string Value;
}

class WideString : public CustomString
{
public:
   WideString (std::wstring _value);
   std::wstring Value
}

What I'm having more difficulty with is the string manipulation methods, say I need .replace, .length and .substr how could I implement these? Would I need to use templates?

virtual T replace(size_t _pos, size_t _len, const T& _str);

Or have two methods for each type and override them in the derived classes?

virtual std::string replace(size_t _pos, size_t _len, const std::string& _str)
virtual std::wstring replace(size_t _pos, size_t _len, const std::wstring& _str)

An example of what the interface would look like using templates and no inheritance:

class CustomString
{
public:
    CustomString();
    CustomString(bool _unicode);

    template <typename T>
    T get();

    template <typename T>
    T replace(size_t _pos, size_t _len, const T& _str);

    long length();

    template <typename T>
    T substr(size_t _off);

    template <typename T>
    T append(const T& _str);

    template <typename T>
    T c_str();

private:
    std::wstring wValue;
    std::string nValue;
    bool unicode;

};

}

Upvotes: 2

Views: 580

Answers (1)

David Haim
David Haim

Reputation: 26496

I suggest doing it in different form:

enum class Encoding{
   UTF8,
   UTF16
};

Encoding readFile(const char* path, std::string& utf8Result,std::wstring& utf16result);

now read the file to the correct object and return the correct encoding as result. the use of this function can write generic code around this function with template generelization around std::basic_string:

template <class T>
void doNext(const std::basic_string<T>& result){/*...*/}

std::string possibleUTF8Result;
std::wstring possibleUTF16Result;
auto res = readFile("text.txt",possibleUTF8Result,possibleUTF16Result);
if (res == Encoding::UTF8){
  doNext(possibleUTF8Result);
} else { doNext(possibleUTF16Result); }

*note: wstring is utf16 on windows but utf32 on linux.

Upvotes: 2

Related Questions