diff --git a/src/array_view.hh b/src/array_view.hh index 6a363656..982b436f 100644 --- a/src/array_view.hh +++ b/src/array_view.hh @@ -30,8 +30,8 @@ public: template constexpr ArrayView(T(&array)[N]) : m_pointer(array), m_size(N) {} - template().data())) == sizeof(T)>> + template + requires (sizeof(decltype(*std::declval().data())) == sizeof(T)) constexpr ArrayView(Container&& c) : m_pointer(c.data()), m_size(c.size()) {} diff --git a/src/commands.cc b/src/commands.cc index fbf14e8e..b7e2195e 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -70,9 +70,8 @@ template<> struct PerArgumentCommandCompleter<> template struct PerArgumentCommandCompleter : PerArgumentCommandCompleter { - template, - std::remove_reference_t>::value>> + template + requires (not std::is_base_of_v, std::remove_reference_t>) PerArgumentCommandCompleter(C&& completer, R&&... rest) : PerArgumentCommandCompleter(std::forward(rest)...), m_completer(std::forward(completer)) {} diff --git a/src/enum.hh b/src/enum.hh index 09e11ef0..bedfea6d 100644 --- a/src/enum.hh +++ b/src/enum.hh @@ -2,12 +2,16 @@ #define enum_hh_INCLUDED #include "string.hh" +#include "meta.hh" namespace Kakoune { template struct EnumDesc { T value; StringView name; }; +template +concept DescribedEnum = requires { enum_desc(Meta::Type{}); }; + } #endif // enum_hh_INCLUDED diff --git a/src/flags.hh b/src/flags.hh index 6b701016..6d4764f3 100644 --- a/src/flags.hh +++ b/src/flags.hh @@ -11,22 +11,19 @@ namespace Kakoune template constexpr bool with_bit_ops(Meta::Type) { return false; } +template +concept WithBitOps = with_bit_ops(Meta::Type{}); + template using UnderlyingType = std::underlying_type_t; -template -using EnableIfWithBitOps = std::enable_if_t{}), T>; - -template -using EnableIfWithoutBitOps = std::enable_if_t{}), T>; - -template> +template constexpr Flags operator|(Flags lhs, Flags rhs) { return (Flags)((UnderlyingType) lhs | (UnderlyingType) rhs); } -template> +template constexpr Flags& operator|=(Flags& lhs, Flags rhs) { (UnderlyingType&) lhs |= (UnderlyingType) rhs; @@ -45,32 +42,32 @@ struct TestableFlags constexpr bool operator!=(const TestableFlags& other) const { return value != other.value; } }; -template> +template constexpr TestableFlags operator&(Flags lhs, Flags rhs) { return { (Flags)((UnderlyingType) lhs & (UnderlyingType) rhs) }; } -template> +template constexpr Flags& operator&=(Flags& lhs, Flags rhs) { (UnderlyingType&) lhs &= (UnderlyingType) rhs; return lhs; } -template> +template constexpr Flags operator~(Flags lhs) { return (Flags)(~(UnderlyingType)lhs); } -template> +template constexpr Flags operator^(Flags lhs, Flags rhs) { return (Flags)((UnderlyingType) lhs ^ (UnderlyingType) rhs); } -template> +template constexpr Flags& operator^=(Flags& lhs, Flags rhs) { (UnderlyingType&) lhs ^= (UnderlyingType) rhs; diff --git a/src/hash.hh b/src/hash.hh index 23ae50a9..8dcd719f 100644 --- a/src/hash.hh +++ b/src/hash.hh @@ -11,16 +11,14 @@ namespace Kakoune size_t hash_data(const char* data, size_t len); -template -std::enable_if_t::value, size_t> -constexpr hash_value(const Type& val) +template requires std::is_integral_v +constexpr size_t hash_value(const Type& val) { return (size_t)val; } -template -std::enable_if_t::value, size_t> -constexpr hash_value(const Type& val) +template requires std::is_enum_v +constexpr size_t hash_value(const Type& val) { return hash_value((std::underlying_type_t)val); } diff --git a/src/hash_map.hh b/src/hash_map.hh index b5f054bc..b7ae4494 100644 --- a/src/hash_map.hh +++ b/src/hash_map.hh @@ -182,12 +182,7 @@ struct HashMap return m_items.back().value; } - template - using EnableIfHashCompatible = std::enable_if_t< - IsHashCompatible> - >; - - template> + template requires IsHashCompatible constexpr int find_index(const KeyType& key, size_t hash) const { for (auto slot = m_index.compute_slot(hash); slot < m_index.size(); ++slot) @@ -201,13 +196,13 @@ struct HashMap return -1; } - template> + template requires IsHashCompatible constexpr int find_index(const KeyType& key) const { return find_index(key, hash_value(key)); } - template> + template requires IsHashCompatible constexpr bool contains(const KeyType& key) const { return find_index(key) >= 0; } - template> + template requires IsHashCompatible> constexpr Value& operator[](KeyType&& key) { const auto hash = hash_value(key); @@ -221,7 +216,7 @@ struct HashMap return m_items.back().value; } - template> + template requires IsHashCompatible constexpr void remove(const KeyType& key) { const auto hash = hash_value(key); @@ -234,7 +229,7 @@ struct HashMap } } - template> + template requires IsHashCompatible constexpr void unordered_remove(const KeyType& key) { const auto hash = hash_value(key); @@ -249,10 +244,10 @@ struct HashMap } } - template> + template requires IsHashCompatible constexpr void erase(const KeyType& key) { unordered_remove(key); } - template> + template requires IsHashCompatible constexpr void remove_all(const KeyType& key) { const auto hash = hash_value(key); @@ -275,14 +270,14 @@ struct HashMap const Item& item(size_t index) const { return m_items[index]; } - template> + template requires IsHashCompatible constexpr iterator find(const KeyType& key) { auto index = find_index(key); return index >= 0 ? begin() + index : end(); } - template> + template requires IsHashCompatible constexpr const_iterator find(const KeyType& key) const { return const_cast(this)->find(key); diff --git a/src/option_types.hh b/src/option_types.hh index e576b295..40d367df 100644 --- a/src/option_types.hh +++ b/src/option_types.hh @@ -19,8 +19,8 @@ namespace Kakoune { template -std::enable_if_t())), String>::value, String> -option_to_string(const T& value, Quoting) +String option_to_string(const T& value, Quoting) + requires std::is_same_v())), String> { return option_to_string(value); } @@ -31,9 +31,8 @@ constexpr decltype(T::option_type_name) option_type_name(Meta::Type) return T::option_type_name; } -template -std::enable_if_t::value, String> -option_type_name(Meta::Type) +template requires std::is_enum_v +String option_type_name(Meta::Type) { return format("{}({})", with_bit_ops(Meta::Type{}) ? "flags" : "enum", join(enum_desc(Meta::Type{}) | @@ -256,8 +255,8 @@ inline String option_to_string(const StronglyTypedNumber& o } template -std::enable_if_t, Number>::value, Number> -option_from_string(Meta::Type, StringView str) + requires std::is_base_of_v, Number> +Number option_from_string(Meta::Type, StringView str) { return Number{str_to_int(str)}; } @@ -290,8 +289,8 @@ inline void option_update(WorstMatch, const Context&) } template -std::enable_if_t, Coord>::value, Coord> -option_from_string(Meta::Type, StringView str) + requires std::is_base_of_v, Coord> +Coord option_from_string(Meta::Type, StringView str) { struct error : runtime_error { error(size_t) : runtime_error{"expected ,"} {} }; auto vals = str | split(',') @@ -305,8 +304,8 @@ inline String option_to_string(const LineAndColumn{}))> -EnableIfWithBitOps option_to_string(Flags flags) +template requires WithBitOps +String option_to_string(Flags flags) { constexpr auto desc = enum_desc(Meta::Type{}); String res; @@ -321,8 +320,8 @@ EnableIfWithBitOps option_to_string(Flags flags) return res; } -template{}))> -EnableIfWithoutBitOps option_to_string(Enum e) +template requires (not WithBitOps) +String option_to_string(Enum e) { constexpr auto desc = enum_desc(Meta::Type{}); auto it = find_if(desc, [e](const EnumDesc& d) { return d.value == e; }); @@ -332,8 +331,8 @@ EnableIfWithoutBitOps option_to_string(Enum e) return {}; } -template{}))> -EnableIfWithBitOps option_from_string(Meta::Type, StringView str) +template requires WithBitOps +Flags option_from_string(Meta::Type, StringView str) { constexpr auto desc = enum_desc(Meta::Type{}); Flags flags{}; @@ -347,8 +346,8 @@ EnableIfWithBitOps option_from_string(Meta::Type, StringVie return flags; } -template{}))> -EnableIfWithoutBitOps option_from_string(Meta::Type, StringView str) +template requires (not WithBitOps) +Enum option_from_string(Meta::Type, StringView str) { constexpr auto desc = enum_desc(Meta::Type{}); auto it = find_if(desc, [str](const EnumDesc& d) { return d.name == str; }); @@ -357,16 +356,16 @@ EnableIfWithoutBitOps option_from_string(Meta::Type, StringVie return it->value; } -template{}))> -EnableIfWithBitOps option_add(Flags& opt, StringView str) +template requires WithBitOps +bool option_add(Flags& opt, StringView str) { const Flags old = opt; opt |= option_from_string(Meta::Type{}, str); return opt != old; } -template{}))> -EnableIfWithBitOps option_remove(Flags& opt, StringView str) +template requires WithBitOps +bool option_remove(Flags& opt, StringView str) { const Flags old = opt; opt &= ~option_from_string(Meta::Type{}, str); diff --git a/src/string_utils.hh b/src/string_utils.hh index e0adc181..a11aaa91 100644 --- a/src/string_utils.hh +++ b/src/string_utils.hh @@ -136,14 +136,12 @@ decltype(auto) to_string(const StronglyTypedNumber& val) namespace detail { -template constexpr bool is_string = std::is_convertible::value; - -template>> -decltype(auto) format_param(const T& val) { return to_string(val); } - -template>> +template requires std::is_convertible_v StringView format_param(const T& val) { return val; } +template requires (not std::is_convertible_v) +decltype(auto) format_param(const T& val) { return to_string(val); } + } String format(StringView fmt, ArrayView params); diff --git a/src/utf8_iterator.hh b/src/utf8_iterator.hh index 81302ef9..618a44a9 100644 --- a/src/utf8_iterator.hh +++ b/src/utf8_iterator.hh @@ -109,12 +109,12 @@ public: bool operator>= (const iterator& other) const noexcept { return m_it >= other.m_it; } template - std::enable_if_t::value or std::is_same::value, bool> - operator==(const T& other) const noexcept { return m_it == other; } + requires std::is_same_v or std::is_same_v + bool operator==(const T& other) const noexcept { return m_it == other; } template - std::enable_if_t::value or std::is_same::value, bool> - operator!=(const T& other) const noexcept { return m_it != other; } + requires std::is_same_v or std::is_same_v + bool operator!=(const T& other) const noexcept { return m_it != other; } bool operator< (const BaseIt& other) const noexcept { return m_it < other; } bool operator<= (const BaseIt& other) const noexcept { return m_it <= other; } diff --git a/src/value.hh b/src/value.hh index 51394c7d..aa53afb8 100644 --- a/src/value.hh +++ b/src/value.hh @@ -16,8 +16,7 @@ struct Value { Value() = default; - template::value>> + template requires (not std::is_same_v) Value(T&& val) : m_value{new Model>{std::forward(val)}} {}