Can you have manipulators in C++ for classes that are not stream (ostream/istream) based

54 Views Asked by At

I am trying to create a boost based log class (gcc/linux) that uses the operator<< in order to write the log. for example: log << debugmsg << "This is my debug message";

I am finding all kinds of information (google) on how to do this with ostream (and probably istream) that I have no issues with.

Can anyone point me in the right direction on how to do something like this. Even the proper keywords to use in my google search would be helpful.

Thank you!

2

There are 2 best solutions below

0
Nicol Bolas On

Any tool can mimic any part of the standard iostream library's behavior. But it has to be part of the tool. You cannot externally make some tool do something that it's not designed to do.

If Boost.Log has standard-equivalent manipulator functionality in it, then you can use that. If it doesn't, but it's extensible enough to add such functionality, then you can use whatever hooks it provides to add that functionality. But if neither of these is the case, there's nothing externally you can do.

You will just have to massage your strings manually to do what the iostream manipulators would have done.

0
Pepijn Kramer On

Manipulators can be anything, a class instance, an enum value you just have to provide the correct overloads for operator<< to handle them. Example : https://onlinegdb.com/W8E7xwqMx.

#include <iostream>

enum class colors_v
{
    red,
    blue,
    green,
    white
};

class console_t final
{
public:
    console_t() = default;
    ~console_t() = default;

    template <typename T>
    console_t& operator<<(const T& t)
    {
        std::cout << t;
        return *this;
    }

    // provide an overload for what you want to control your stream with
    // in this case an enum type, but it can just as well be a manipulator class instance you then get the information from.
    console_t& operator<<(const colors_v& color)
    {
        switch (color)
        {
        case colors_v::red:
            std::cout << "\033[1;31m";
        break;

        case colors_v::green:
            std::cout << "\033[1;32m";
        break;

        case colors_v::blue:
            std::cout << "\033[1;34m";
        break;
        
        case colors_v::white:
        default:
            std::cout << "\033[1;37m";
        break;
        }

        return *this;
    }
};


int main()
{
    console_t console;
    console << colors_v::red << "Hello " << colors_v::green << "world" << colors_v::blue << "!";
    return 0;
}