diff --git a/doc/en/build.md b/doc/en/build.md index 0b72578..2d555de 100644 --- a/doc/en/build.md +++ b/doc/en/build.md @@ -1,6 +1,6 @@ # Building ## Prerequisites -1. Compiler that supports C++20. Recommended compilers: `MSVC 19.3` (`Visual Studio 2022`) or higher, `GCC 12` or higher. +1. Compiler that supports C++20. Recommended compilers: `MSVC 19.3` (`Visual Studio 2022`) or higher, `GCC 12` or higher, `Clang 14` or higher. 2. `CMake`: `3.20` or higher. 3. `GoogleTest` (optional): Only required when building unit tests. diff --git a/doc/zh-CN/build.md b/doc/zh-CN/build.md index c5a0586..aef4e38 100644 --- a/doc/zh-CN/build.md +++ b/doc/zh-CN/build.md @@ -1,6 +1,6 @@ # 构建 ## 前置要求 -1. 任意支持 C++20 的编译器,推荐:`MSVC 19.3`(`Visual Studio 2022`)或以上、`GCC 12` 或以上 +1. 任意支持 C++20 的编译器,推荐:`MSVC 19.3`(`Visual Studio 2022`)或以上、`GCC 12` 或以上、`Clang 14` 或以上 2. `CMake`:`3.20` 或以上 3. `GoogleTest` (可选):仅构建单元测试时需要 diff --git a/example/info.cpp b/example/info.cpp index 1b3ae94..f8622e8 100644 --- a/example/info.cpp +++ b/example/info.cpp @@ -15,6 +15,9 @@ int main() #ifdef PAPILIO_COMPILER_GCC println("PAPILIO_COMPILER_GCC = {}", PAPILIO_COMPILER_GCC); #endif +#ifdef PAPILIO_COMPILER_CLANG + println("PAPILIO_COMPILER_CLANG = {}", PAPILIO_COMPILER_CLANG); +#endif #ifdef PAPILIO_HAS_MULTIDIMENSIONAL_SUBSCRIPT println("PAPILIO_HAS_MULTIDIMENSIONAL_SUBSCRIPT = {:d}L", PAPILIO_HAS_MULTIDIMENSIONAL_SUBSCRIPT); diff --git a/example/playground/ipapilio.hpp b/example/playground/ipapilio.hpp index eb0414f..a4b5e93 100644 --- a/example/playground/ipapilio.hpp +++ b/example/playground/ipapilio.hpp @@ -27,6 +27,9 @@ class ipapilio std::string help; callback_t callback; + + command_data(std::string h, callback_t cb) + : help(std::move(h)), callback(cb) {} }; std::map> m_cmds; diff --git a/include/papilio/access/tuple.hpp b/include/papilio/access/tuple.hpp index 509a0b1..d9e5e90 100644 --- a/include/papilio/access/tuple.hpp +++ b/include/papilio/access/tuple.hpp @@ -21,7 +21,7 @@ struct tuple_accessor using format_arg_type = basic_format_arg; [[nodiscard]] - static consteval std::size_t size() noexcept + static constexpr std::size_t size() noexcept { return std::tuple_size_v; } diff --git a/include/papilio/container.hpp b/include/papilio/container.hpp index ea4653f..10d1724 100644 --- a/include/papilio/container.hpp +++ b/include/papilio/container.hpp @@ -47,8 +47,8 @@ class small_vector_base : public detail::small_vector_impl using difference_type = std::ptrdiff_t; using reference = value_type&; using const_reference = const value_type&; - using pointer = std::allocator_traits::pointer; - using const_pointer = std::allocator_traits::const_pointer; + using pointer = typename std::allocator_traits::pointer; + using const_pointer = typename std::allocator_traits::const_pointer; using iterator = pointer; using const_iterator = const_pointer; using reverse_iterator = std::reverse_iterator; @@ -250,12 +250,12 @@ class small_vector : public small_vector_base using difference_type = std::ptrdiff_t; using reference = value_type&; using const_reference = const value_type&; - using pointer = my_base::pointer; - using const_pointer = my_base::const_pointer; - using iterator = my_base::iterator; - using const_iterator = my_base::const_iterator; - using reverse_iterator = my_base::reverse_iterator; - using const_reverse_iterator = my_base::const_reverse_iterator; + using pointer = typename my_base::pointer; + using const_pointer = typename my_base::const_pointer; + using iterator = typename my_base::iterator; + using const_iterator = typename my_base::const_iterator; + using reverse_iterator = typename my_base::reverse_iterator; + using const_reverse_iterator = typename my_base::const_reverse_iterator; small_vector() noexcept(std::is_nothrow_default_constructible_v) : my_base(), m_data() @@ -708,7 +708,6 @@ class small_vector : public small_vector_base PAPILIO_ASSERT(this->size() < this->capacity()); size_type tmp_size = this->size(); - size_type tmp_capacity = this->capacity(); pointer tmp_ptr = std::allocator_traits::allocate( getal(), tmp_size ); @@ -1169,8 +1168,8 @@ class fixed_flat_map : public detail::fixed_flat_map_impl using key_compare = Compare; using reference = value_type&; using const_reference = value_type&; - using iterator = underlying_type::iterator; - using const_iterator = underlying_type::const_iterator; + using iterator = typename underlying_type::iterator; + using const_iterator = typename underlying_type::const_iterator; class value_compare : public detail::value_compare_base> diff --git a/include/papilio/core.hpp b/include/papilio/core.hpp index dcd4e73..f63d4fc 100755 --- a/include/papilio/core.hpp +++ b/include/papilio/core.hpp @@ -174,7 +174,7 @@ class basic_format_arg { public: using value_type = std::remove_cvref_t; - using accessor_t = handle_impl::accessor_t; + using accessor_t = typename handle_impl::accessor_t; handle_impl_ptr(const T& val) noexcept : m_ptr(std::addressof(val), false) {} @@ -235,7 +235,7 @@ class basic_format_arg { public: using value_type = std::remove_cvref_t; - using accessor_t = handle_impl::accessor_t; + using accessor_t = typename handle_impl::accessor_t; template requires std::is_constructible_v @@ -415,7 +415,7 @@ class basic_format_arg void construct_impl(Args&&... args) { static_assert(detail::use_handle); - static_assert(sizeof(Impl) <= m_storage.size()); + static_assert(sizeof(Impl) <= storage_size); new(ptr()) Impl(std::forward(args)...); } @@ -806,7 +806,7 @@ namespace detail return idx.visit( [this](const T& v) -> bool { - if constexpr(std::is_same_v) + if constexpr(std::is_same_v) { if(v < 0) return false; @@ -912,7 +912,7 @@ class static_format_args final : public detail::format_args_base using my_base::get; [[nodiscard]] - bool check(string_view_type key) const noexcept + bool check(string_view_type key) const noexcept override { return m_named_args.contains(key); } @@ -1394,7 +1394,7 @@ class basic_format_parse_context using string_type = std::basic_string; using string_view_type = std::basic_string_view; using string_ref_type = utf::basic_string_ref; - using const_iterator = string_ref_type::const_iterator; + using const_iterator = typename string_ref_type::const_iterator; using iterator = const_iterator; using size_type = std::size_t; using format_context_type = FormatContext; @@ -1499,13 +1499,19 @@ namespace detail { // clang-format off - template >> + template < + typename T, + typename Context, + typename Formatter = typename Context::template formatter_type>> concept formattable_with_impl = std::semiregular && - requires(Formatter& f, const Formatter& cf, T&& val, Context fmt_ctx, basic_format_parse_context parse_ctx) - { - { f.parse(parse_ctx) } -> std::same_as; - { cf.format(val, fmt_ctx) } -> std::same_as; + requires(Formatter& f, const Formatter& cf, T&& val, Context fmt_ctx, basic_format_parse_context parse_ctx) { + { + f.parse(parse_ctx) + } -> std::same_as; + { + cf.format(val, fmt_ctx) + } -> std::same_as; }; // clang-format on diff --git a/include/papilio/core.inl b/include/papilio/core.inl index f08c185..4e5e113 100644 --- a/include/papilio/core.inl +++ b/include/papilio/core.inl @@ -15,7 +15,7 @@ void basic_format_arg::handle_impl_ptr::format(parse_context& parse_ { if constexpr(formattable_with) { - using formatter_t = Context::template formatter_type; + using formatter_t = typename Context::template formatter_type; formatter_t fmt; parse_ctx.advance_to(fmt.parse(parse_ctx)); @@ -34,7 +34,7 @@ void basic_format_arg::handle_impl_soo::format(parse_context& parse_ { if constexpr(formattable_with) { - using formatter_t = Context::template formatter_type; + using formatter_t = typename Context::template formatter_type; formatter_t fmt; parse_ctx.advance_to(fmt.parse(parse_ctx)); @@ -77,7 +77,7 @@ void basic_format_arg::format(parse_context& parse_ctx, Context& out_ct } else if constexpr(formattable_with) { - using formatter_t = Context::template formatter_type; + using formatter_t = typename Context::template formatter_type; formatter_t fmt; parse_ctx.advance_to(fmt.parse(parse_ctx)); diff --git a/include/papilio/detail/compat.hpp b/include/papilio/detail/compat.hpp index 152afdf..38d1d75 100644 --- a/include/papilio/detail/compat.hpp +++ b/include/papilio/detail/compat.hpp @@ -13,17 +13,14 @@ inline void unreachable() std::unreachable(); #elif defined PAPILIO_COMPILER_MSVC __assume(false); -#elif defined PAPILIO_COMPILER_GCC +#elif defined PAPILIO_COMPILER_GCC || defined PAPILIO_COMPILER_CLANG __builtin_unreachable(); - - // TODO: Clang support - #else // An empty function body and the [[noreturn]] attribute is enough to raise undefined behavior. #endif } -// forwark_like of C++ 23 +// forward_like of C++ 23 // Use implementation from cppreference.com PAPILIO_EXPORT template [[nodiscard]] diff --git a/include/papilio/macros.hpp b/include/papilio/macros.hpp index 25a91fc..a2f3949 100644 --- a/include/papilio/macros.hpp +++ b/include/papilio/macros.hpp @@ -21,11 +21,13 @@ # define PAPILIO_COMPILER_MSVC _MSC_VER #endif #ifdef __GNUC__ -# define PAPILIO_COMPILER_GCC __GNUC__ +# ifndef __clang__ +# define PAPILIO_COMPILER_GCC __GNUC__ +# else +# define PAPILIO_COMPILER_CLANG __clang_major__ +# endif #endif -// TODO: Clang support - #define PAPILIO_ASSERT(expr) assert(expr) #if defined(_WIN32) || defined(_WIN64) diff --git a/include/papilio/script/interpreter.hpp b/include/papilio/script/interpreter.hpp index 19ad9ce..6c08a6b 100644 --- a/include/papilio/script/interpreter.hpp +++ b/include/papilio/script/interpreter.hpp @@ -708,7 +708,7 @@ class basic_interpreter_base : public script_base if constexpr(char8_like) { - auto result = std::from_chars( + std::from_chars( std::bit_cast(start.base()), std::bit_cast(stop.base()), val @@ -717,7 +717,7 @@ class basic_interpreter_base : public script_base else { std::string tmp = string_ref_type(start, stop).to_string(); - auto result = std::from_chars( + std::from_chars( std::to_address(tmp.begin()), std::to_address(tmp.end()), val @@ -895,7 +895,7 @@ class basic_interpreter : using parse_context = basic_format_parse_context; - using iterator = my_base::iterator; + using iterator = typename my_base::iterator; static_assert(std::is_same_v); basic_interpreter() = default; @@ -1111,7 +1111,7 @@ class basic_interpreter : } else { - using int_t = variable_type::int_type; + using int_t = typename variable_type::int_type; int_t val = my_base::template parse_integer(start, int_end).first; return std::make_pair(val, int_end); diff --git a/include/papilio/utf/codepoint.hpp b/include/papilio/utf/codepoint.hpp index bad05d9..f7a1768 100644 --- a/include/papilio/utf/codepoint.hpp +++ b/include/papilio/utf/codepoint.hpp @@ -228,6 +228,8 @@ PAPILIO_EXPORT class codepoint return *this; } + constexpr codepoint& operator=(const codepoint&) noexcept = default; + constexpr void clear() noexcept { m_data[0] = 0; diff --git a/include/papilio/utf/string.hpp b/include/papilio/utf/string.hpp index a31edad..f65dab1 100644 --- a/include/papilio/utf/string.hpp +++ b/include/papilio/utf/string.hpp @@ -40,6 +40,8 @@ namespace detail constexpr const_str_iter_impl() noexcept = default; constexpr const_str_iter_impl(const const_str_iter_impl&) noexcept = default; + constexpr const_str_iter_impl& operator=(const const_str_iter_impl&) noexcept = default; + protected: constexpr const_str_iter_impl(string_view_type str, size_type offset, std::uint8_t len) noexcept : m_str(str), m_offset(offset), m_len(len) {} @@ -150,6 +152,8 @@ namespace detail constexpr const_str_iter_impl() noexcept = default; constexpr const_str_iter_impl(const const_str_iter_impl&) noexcept = default; + constexpr const_str_iter_impl& operator=(const const_str_iter_impl&) noexcept = default; + protected: constexpr const_str_iter_impl(string_view_type str, size_type offset, std::uint8_t len) noexcept : m_str(str), m_offset(offset), m_len(len) {} @@ -238,8 +242,13 @@ namespace detail constexpr const_str_iter_impl() noexcept = default; constexpr const_str_iter_impl(const const_str_iter_impl&) noexcept = default; + constexpr const_str_iter_impl& operator=(const const_str_iter_impl&) noexcept = default; + + private: + using base_iter_t = typename string_view_type::const_iterator; + protected: - constexpr const_str_iter_impl(string_view_type::const_iterator iter) noexcept + constexpr const_str_iter_impl(base_iter_t iter) noexcept : m_iter(iter) {} constexpr void next() noexcept @@ -288,7 +297,7 @@ namespace detail } private: - string_view_type::const_iterator m_iter; + base_iter_t m_iter; }; class str_static_base @@ -833,9 +842,9 @@ class basic_string_ref : public detail::str_base; using string_view_type = std::basic_string_view; - using const_iterator = my_base::const_iterator; + using const_iterator = typename my_base::const_iterator; using iterator = const_iterator; - using const_reverse_iterator = my_base::const_reverse_iterator; + using const_reverse_iterator = typename my_base::const_reverse_iterator; using reverse_iterator = const_reverse_iterator; constexpr basic_string_ref() noexcept = default; @@ -1260,8 +1269,8 @@ class basic_string_container : public detail::str_base; using string_ref_type = basic_string_ref; - using const_iterator = my_base::const_iterator; - using const_reverse_iterator = my_base::const_reverse_iterator; + using const_iterator = typename my_base::const_iterator; + using const_reverse_iterator = typename my_base::const_reverse_iterator; basic_string_container() noexcept = default; basic_string_container(std::nullptr_t) = delete; diff --git a/include/papilio/utility.hpp b/include/papilio/utility.hpp index fcf1654..1cba866 100644 --- a/include/papilio/utility.hpp +++ b/include/papilio/utility.hpp @@ -302,7 +302,9 @@ inline namespace literals PAPILIO_EXPORT template struct independent_proxy : public std::reference_wrapper -{}; +{ + using std::reference_wrapper::reference_wrapper; +}; PAPILIO_EXPORT struct independent_t { @@ -623,7 +625,7 @@ namespace detail return *this; } - constexpr void swap(compressed_pair_impl& other) noexcept + constexpr void swap(compressed_pair_impl&) noexcept { // empty } @@ -698,8 +700,8 @@ class basic_iterbuf : public: using char_type = CharT; using iterator = Iterator; - using int_type = base::int_type; - using traits_type = base::traits_type; + using int_type = typename base::int_type; + using traits_type = typename base::traits_type; basic_iterbuf() = default; diff --git a/test/test_format.cpp b/test/test_format.cpp index bc02678..c6ca2d8 100644 --- a/test/test_format.cpp +++ b/test/test_format.cpp @@ -139,7 +139,7 @@ class yes_no_numpunct : public std::numpunct using base = std::numpunct; public: - using string_type = base::string_type; + using string_type = typename base::string_type; protected: string_type do_truename() const override @@ -262,6 +262,9 @@ struct large_unformattable_type struct custom_type { int val = 0; + + custom_type(int v) + : val(v) {} }; struct large_custom_type diff --git a/test/test_utility.cpp b/test/test_utility.cpp index 9b02c2c..4bb6d80 100644 --- a/test/test_utility.cpp +++ b/test/test_utility.cpp @@ -283,11 +283,9 @@ TEST(basic_oiterstream, char) using namespace papilio; std::string buf; - oiterstream os(std::back_inserter(buf)); - - static_assert(std::is_same_v< - decltype(os)::iterator, - std::back_insert_iterator>); + oiterstream> os( + std::back_inserter(buf) + ); os << "hello"; os << ' '; @@ -302,11 +300,9 @@ TEST(basic_oiterstream, wchar_t) using namespace papilio; std::wstring buf; - woiterstream os(std::back_inserter(buf)); - - static_assert(std::is_same_v< - decltype(os)::iterator, - std::back_insert_iterator>); + woiterstream> os( + std::back_inserter(buf) + ); os << L"hello"; os << L' ';