#ifndef INCLUDE_GUARD_SYNCSTREAM_H
#define INCLUDE_GUARD_SYNCSTREAM_H

#include <ostream>
#include <mutex>

class osyncstream {
public:
    osyncstream(std::ostream& base_ostream)
        : _base_ostream(base_ostream)
    {
        mtx().lock();
    }

    ~osyncstream() {
        mtx().unlock();
    }

    template <typename T>
    osyncstream& operator<<(const T& rhs) {
        _base_ostream << rhs;
        return *this;
    }

    osyncstream& operator<<(std::ostream& (*fn)(std::ostream&)) {
        _base_ostream << fn;
        return *this;
    }

private:
    std::mutex& mtx() {
        static std::mutex _mtx;
        return _mtx;
    };
    std::ostream& _base_ostream;
};

#endif /* INCLUDE_GUARD_SYNCSTREAM_H */
