Skip to content

Commit

Permalink
Work around clang not inferring default args of template template args
Browse files Browse the repository at this point in the history
Clang 16 fails to compile calls like "gather<Vector>()".

	c++  -O3 -pedantic -std=c++2a -g -Wall -Wextra -Wno-unused-parameter -Wno-sign-compare -Wno-address -frelaxed-template-template-args -Wno-ambiguous-reversed-operator -MD -MP -MF .command_manager.opt.d -c -o .command_manager.opt.o command_manager.cc
	command_manager.cc:825:104: error: no matching function for call to 'gather'
	        auto params = tokens | skip(1) | transform(&Token::content) | filter(std::not_fn(is_switch)) | gather<Vector>();
	                                                                                                       ^~~~~~~~~~~~~~
	./ranges.hh:633:6: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'Container'
	auto gather()
	     ^
	./ranges.hh:642:6: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'Container'
	auto gather()
	     ^
	1 error generated.

because Vector has a defaulted template argument but gather's formal
parameter.

Upstream bug report: llvm/llvm-project#42224
(not sure why it worked for us with Clang 15).

Work around this by adding gather() overloads whose template template
parameter clang can match against Vector. Add another one for HashSet.

GCC rejects calls to these overloads as ambiguous, so use conditional
compilation.

Fixes mawww#4872
  • Loading branch information
krobelus committed May 9, 2023
1 parent 2adc81c commit 348c556
Showing 1 changed file with 36 additions and 0 deletions.
36 changes: 36 additions & 0 deletions src/ranges.hh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
#include <tuple>

#include "constexpr_utils.hh"
#ifdef __clang__
#include "memory.hh"
#include "meta.hh"
#include "vector.hh"
#endif

namespace Kakoune
{
Expand Down Expand Up @@ -638,6 +643,35 @@ auto gather()
}};
}

#ifdef __clang__

template <template <typename T,
MemoryDomain domain = memory_domain(Meta::Type<T>{})>
class Container>
auto gather()
{
return ViewFactory{[](auto&& range) {
using std::begin; using std::end;
using ValueType = std::remove_cv_t<std::remove_reference_t<decltype(*begin(range))>>;
return Container<ValueType>(begin(range), end(range));
}};
}

template <template <typename T,
MemoryDomain domain = MemoryDomain::Undefined,
template<typename, MemoryDomain> class C = Vector>
class Container>
auto gather()
{
return ViewFactory{[](auto&& range) {
using std::begin; using std::end;
using ValueType = std::remove_cv_t<std::remove_reference_t<decltype(*begin(range))>>;
return Container<ValueType>(begin(range), end(range));
}};
}

#else

template<template <typename Element> class Container>
auto gather()
{
Expand All @@ -648,6 +682,8 @@ auto gather()
}};
}

#endif

template<typename ExceptionType, bool exact_size, size_t... Indexes>
auto elements()
{
Expand Down

0 comments on commit 348c556

Please sign in to comment.