Skip to content

Broken back insert iterator traits #4454

@uentity

Description

@uentity

Hi @vitaut

Among recent changes in v11 you've refactored traits for testing if type is a specialization of std::back_insert_iterator.
As a result, the following static assert no longer works:

#include <fmt/format.h>
#include <iterator>

using It = decltype(std::back_inserter(std::declval<fmt::memory_buffer&>()));
static_assert(fmt::detail::is_back_insert_iterator<It>::value);

This impacts e.g. fmt::format_to() that fails to select an optimized overload for std::back_insert_iterator<fmt::memory_buffer> and becomes horribly slow. I actually discovered this issue while working on a benchmark where I noticed that formatting to a preallocated fmt::memory_buffer is for some reason much slower than fmt::format().

To fix the issue you need to swap the headers order, i.e. make sure <iterator> is included before <fmt/base.h> s.t. ADL can really see the back_inserter(std::declval<Container&>()):

#include <iterator>
#include <fmt/format.h>

using It = decltype(std::back_inserter(std::declval<fmt::memory_buffer&>()));
static_assert(fmt::detail::is_back_insert_iterator<It>::value);

I suppose the easiest way to fix this is either revert to prev version of traits (which IMO is quite fine) or include <iterator> in the fmt/base.h.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions