namespace strf {

template <typename CharT>
constexpr std::size_t min_space_after_recycle();

template <typename CharT>
class basic_outbuff
{ /* ... */ };

template <typename CharT>
void put(basic_outbuff<CharT>& ob, CharT c);

template <typename CharT>
class basic_cstr_writer final: public basic_outbuff<CharT>
{ /* ... */};

template <typename CharT>
class discarded_outbuff final: public basic_outbuff<CharT>
{ /* ... */};

template <typename CharT>
CharT* garbage_buff();

template <typename CharT>
CharT* garbage_buff_end();

using bin_outbuff     = basic_outbuff<std::byte>;
using u8outbuff       = basic_outbuff<char8_t>;
using outbuff         = basic_outbuff<char>;
using u16outbuff      = basic_outbuff<char16_t>;
using u32outbuff      = basic_outbuff<char32_t>;
using woutbuff        = basic_outbuff<wchar_t>;

using u8cstr_writer  = basic_cstr_writer<char8_t>;
using cstr_writer    = basic_cstr_writer<char>;
using u16cstr_writer = basic_cstr_writer<char16_t>;
using u32cstr_writer = basic_cstr_writer<char32_t>;
using wcstr_writer   = basic_cstr_writer<wchar_t>;

} // namespace strf

1. Function template min_space_after_recycle

template <typename CharT>
constexpr std::size_t min_space_after_recycle();
Return value

Implementation-defined value greater than or equal to 64.

2. Class template basic_outbuff

2.1. Synopsis

namespace strf {

template <typename CharT>
class basic_outbuff;
{
public:

    using char_type = CharT;

    basic_outbuff(const basic_outbuff&) = delete;
    basic_outbuff(basic_outbuff&&) = delete;
    basic_outbuff& operator=(const basic_outbuff&) = delete;
    basic_outbuff& operator=(basic_outbuff&&) = delete;

    virtual ~basic_outbuff() = default;

    CharT* pointer() const noexcept;
    CharT* end() const noexcept;
    std::size_t space() const noexcept;
    bool good() const noexcept;
    void advance_to(CharT* p);
    void advance(std::size_t n);
    void require(std::size_t s);

    void write(const CharT* str, std::size_t str_len);

    virtual void recycle() = 0;

protected:

    basic_outbuff(CharT* pointer_, CharT* end_);

    basic_outbuff(CharT* pointer_, std::size_t n);

    void set_pointer(CharT* p) noexcept;
    void set_end(CharT* e) noexcept;
    void set_good(bool g) noexcept;

    virtual void do_write(const CharT* str, std::size_t str_len);
};

// global functions

template <typename CharT>
void put( basic_outbuff<CharT>& ob, CharT ch );

} // namespace strf

2.2. Member types

using char_type = CharT;

2.3. Public member functions

CharT* pointer() const noxcept;
Return

The memory position where the content shall be written.

CharT* end() const noxcept;
Return

The end of memory position where the content shall be written. Dereferencing end() has undefined behaviour.

std::size_t space() const noexcept;
Return

end() - pointer()

virtual void recycle() = 0;
Posconditions
void require(std::size_t s)
Effect

Calls recycle() if space() < s.

Precondition

s <= min_space_after_recycle<CharT>()

Postcondition

space() >= s

void advance_to(CharT* p)
Effect

Advance the buffer’s pointer to p.

Precondition

pointer() <= p && p <= end()

Postcondition

pointer() == p

void advance(std::size_t n)
Effect

Equivalent to advance_to(pointer() + n)

Precondition

n <= space()

void advance()
Effect

Equivalent to advance_to(1)

Precondition

pointer() != end()

bool good() const;
Return

The state of this object.

Semantincs

good() == false means that writting anything on pointer(), and calling advance_to and recycle() has no relevant side effect besides their postconditions.

Note

The range [ pointer(), end() ) shall aways be a valid accessible memory, even when good() returns false.

void write(const CharT* str, std::size_t str_len);
Effect

If str_len <= space() is true, copy str_len characters of string the str into pointer() and calls advance(str_len). Otherwise, calls do_write(str, str_len).

2.4. Protected Member functions

basic_outbuff(CharT* pointer_, CharT* end_)
Preconditions
  • pointer_ <= end_

  • The range [ pointer_, end_ ) must be an accessible memory area.

Posconditions
basic_outbuff(CharT* pointer_, std::size_t n)
Preconditions
  • The range [ pointer_, `pointer_ + n ` ) must be an accessible memory area.

Posconditions
void set_pointer(CharT* p) noexcept
Postconditions

pointer() == p

void set_end(CharT* e) noexcept
Postconditions

end() == e

void set_good(bool g) noexcept
Postconditions

good() == g

virtual void do_write(const CharT* str, std::size_t str_len);
Effect

Writes the first str_len characters of string str into this object, calling recycle() how many time it is necessary.

Note

This function is made virtual so that any derived classes can override it with an optimized version.

2.5. Global functions

template <typename CharT>
void put(basic_outbuff<CharT>& ob, CharT ch);
Effect

Equivalent to:

if (ob.space() == 0) {
    ob.recycle();
}
*ob.pointer() = ch;
ob.advance();

3. Class template basic_cstr_writer

namespace strf {

template <typename CharT>
class basic_cstr_writer final: public {basic_outbuff}<CharT> {
public:
    basic_cstr_writer(CharT* dest, CharT* dest_end) noexcept;

    basic_cstr_writer(CharT* dest, std::size_t len) noexcept;

    template <std::size_t N>
    basic_cstr_writer(CharT (&dest)[N]) noexcept;

    basic_cstr_writer(const basic_cstr_writer&) = delete;

    void recycle() noexcept override;

    struct result {
        CharT* ptr;
        bool truncated;
    };

    result finish() noexcept;
};

} // namespace strf

3.1. Public member functions

basic_cstr_writer(CharT* dest, CharT* dest_end) noexcept;
Precondition

dest < dest_end

Postconditions
basic_cstr_writer(CharT* dest, std::size_t dest_size) noexcept;
Precondition

dest_size != 0

Postconditions
template <std::size_t N>
basic_cstr_writer(CharT (&dest)[N]) noexcept;
Postconditions
void recycle() noexcept;
Postconditions
result finish() noexcept;
Effects
  • Assign to '\0' the position after the last written character in memory area used to initialize this object and set this object into "bad" state.

Return value
  • result::truncated is true if recycle or finish has ever been called in this object.

  • result::ptr points to the termination character '\0'.

Postconditions

4. Class template basic_char_array_writer

namespace strf {
template <typename CharT>
class basic_char_array_writer final : public {basic_outbuff}<CharT> {
public:
    template <std::size_t N>
    basic_char_array_writer(CharT (&dest)[N]) noexcept;
    basic_char_array_writer(CharT* dest, CharT* dest_end) noexcept;
    basic_char_array_writer(CharT* dest, std::size_t dest_size) noexcept;
    basic_char_array_writer(const basic_char_array_writer&) noexcept;

    basic_char_array_writer& operator=(const basic_char_array_writer&) noexcept;
    bool operator==(const basic_char_array_writer&) noexcept;

    void recycle() noexcept override;

    struct result {
        CharT* ptr;
        bool truncated;
    };

    result finish() noexcept;
};
} // namespace strf

4.1. Public member functions

template <std::size_t N>
basic_char_array_writer(CharT (&dest)[N]) noexcept;
Postconditions
basic_char_array_writer(CharT* dest, CharT* dest_end) noexcept;
Precondition

dest < dest_end

Postconditions
basic_char_array_writer(CharT* dest, std::size_t dest_size) noexcept;
Precondition

dest_size != 0

Postconditions
void recycle() noexcept;
Postconditions
result finish() noexcept;
Return value
  • result.truncated is true when recycle() or do_write(…​) has been previously called in this object, which means that the the range which with it was initialized is too small.

  • result::ptr is the one-past-the-end pointer of the characters written. However, when result.truncated is true, the number of characters written is unspecified.

5. Class template discarded_outbuff

discarded_outbuff it’s the library’s analogous to /dev/null. A discarded_outbuff object ignores anything written to it.

namespace strf {

template <typename CharT>
class discarded_outbuff final: public basic_outbuff<CharT>
{
public:
    discarded_outbuff() noexcept;
    void recycle() noexcept override;
};

} // namespace strf
discarded_outbuff() noexcept;
Postconditions
void recycle() noexcept;
Postconditions

6. Garbage buffer

These function templates return the begin and the end of a memory area that is never supposed to be read. It can be used when implementing a class that derives from basic_outbuff to set the buffer when the state is "bad".

template <typename CharT>
CharT* garbage_buff() noexcept;
template <typename CharT>
CharT* garbage_buff_end() noexcept;