Customization

The definitions for sequences allow for the possibility of user-defined types to act as custom sequences. The library provides a set of customization points so its algorithms can be optimized for these types. Customization points are implementing as overloads of a function named tag_invoke found by argument dependent lookup. For example, here is a custom sequence which implements the size customization point:

struct custom_sequence
{
    struct iterator;

    iterator begin()    const noexcept;
    iterator end()      const noexcept;

    /** Return the total number of bytes in the sequence.

        This function is intended to be found via
        argument-dependent lookup only.
    */
    friend
    std::size_t
    tag_invoke(
        buffers::size_tag const&,
        custom_sequence const& bs ) noexcept
    {
        return bs.size_impl();
    }

private:
    std::size_t size_impl() const noexcept;
};
For maximum compile-time efficiency, overloads of tag_invoke for a specific type should be declared as hidden friends \[1\] of that type. That is, the definition for the function should be in the class declaration, and no out-of-class or namespace-scope declarations should exist.

These are the available customization points and tags:

tag Signature Semantics, Pre/Post-conditions

size_tag

std::size_t
tag_invoke(
    size_tag const&,
    T const& )

Return the total number of bytes represented by a buffer sequence object.

slice_tag

void
tag_invoke(
    slice_tag const&,
    T&,
    slice_how how,
    std::size_t n )

Remove a number of bytes from a buffer sequence object, modifying the object in place.