Skip to content

Commit

Permalink
refactor: make code compatible with gcc 11/12/13 and clang 16/17 (#76)
Browse files Browse the repository at this point in the history
  • Loading branch information
Viatorus authored Nov 1, 2023
1 parent b0cdb42 commit 265ac25
Show file tree
Hide file tree
Showing 14 changed files with 114 additions and 92 deletions.
3 changes: 3 additions & 0 deletions .clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ Checks: >
-bugprone-exception-escape,
-cppcoreguidelines-pro-bounds-pointer-arithmetic,
-cppcoreguidelines-pro-bounds-constant-array-index,
-cppcoreguidelines-avoid-do-while,
-cppcoreguidelines-avoid-const-or-ref-data-members,
WarningsAsErrors: ''

Expand Down
38 changes: 27 additions & 11 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ jobs:
- name: Install clang-format and clang-tidy
run: |
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
sudo add-apt-repository 'deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-15 main'
sudo apt update && sudo apt install -y clang-format-15 clang-tidy-15
sudo add-apt-repository 'deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-17 main'
sudo apt update && sudo apt install -y clang-format-17 clang-tidy-17
sudo update-alternatives --remove-all clang-format || true
sudo update-alternatives --remove-all clang-tidy || true
sudo update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-15 1000
sudo update-alternatives --install /usr/bin/clang-tidy clang-tidy /usr/bin/clang-tidy-15 1000
sudo update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-17 1000
sudo update-alternatives --install /usr/bin/clang-tidy clang-tidy /usr/bin/clang-tidy-17 1000
clang-tidy --version
clang-format --version
Expand All @@ -43,7 +43,7 @@ jobs:
unit-tests:
strategy:
matrix:
compiler: [ gcc, clang ]
compiler: [ gcc-11, gcc-12, gcc-13, clang-16, clang-17 ]
build_type: [ Debug, Release ]

runs-on: ubuntu-22.04
Expand All @@ -53,16 +53,32 @@ jobs:

- name: Install Compiler
run: |
if [[ "$compiler" == "gcc" ]]; then
if [[ "$compiler" == "gcc-11" ]]; then
sudo apt update && sudo apt install -y gcc-11 g++-11
echo "CC=gcc-11" >> $GITHUB_ENV
echo "CXX=g++-11" >> $GITHUB_ENV
else
elif [[ "$compiler" == "gcc-12" ]]; then
sudo apt update && sudo apt install -y gcc-12 g++-12
echo "CC=gcc-12" >> $GITHUB_ENV
echo "CXX=g++-12" >> $GITHUB_ENV
elif [[ "$compiler" == "gcc-13" ]]; then
sudo apt-get install build-essential software-properties-common -y
sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
sudo apt update && sudo apt install -y gcc-13 g++-13
echo "CC=gcc-13" >> $GITHUB_ENV
echo "CXX=g++-13" >> $GITHUB_ENV
elif [[ "$compiler" == "clang-16" ]]; then
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
sudo add-apt-repository 'deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-15 main'
sudo apt update && sudo apt install -y clang-15
echo "CC=clang-15" >> $GITHUB_ENV
echo "CXX=clang++-15" >> $GITHUB_ENV
sudo add-apt-repository 'deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-16 main'
sudo apt update && sudo apt install -y clang-16
echo "CC=clang-16" >> $GITHUB_ENV
echo "CXX=clang++-16" >> $GITHUB_ENV
elif [[ "$compiler" == "clang-17" ]]; then
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
sudo add-apt-repository 'deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-17 main'
sudo apt update && sudo apt install -y clang-17
echo "CC=clang-17" >> $GITHUB_ENV
echo "CXX=clang++-17" >> $GITHUB_ENV
fi
env:
compiler: ${{ matrix.compiler }}
Expand Down
2 changes: 1 addition & 1 deletion cmake/dev-mode.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ if (BUILD_TESTING)
Include(FetchContent)
FetchContent_Declare(
Catch2
GIT_TAG v3.1.0
GIT_TAG v3.4.0
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_SHALLOW TRUE
)
Expand Down
6 changes: 3 additions & 3 deletions include/emio/detail/conversion.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,11 @@ constexpr size_t count_digits(T number) noexcept {
if constexpr (Base == 10) {
return count_digits_10(number);
} else if constexpr (Base == 2) {
return std::bit_width(number);
return static_cast<size_t>(std::bit_width(number));
} else if constexpr (Base == 8) {
return (std::bit_width(number) + 2) / 3;
return static_cast<size_t>((std::bit_width(number) + 2) / 3);
} else if constexpr (Base == 16) {
return (std::bit_width(number) + 3) / 4;
return static_cast<size_t>(((std::bit_width(number) + 3) / 4));
} else {
size_t digit_cnt{1};
for (number /= static_cast<T>(Base); number; number /= static_cast<T>(Base)) {
Expand Down
12 changes: 7 additions & 5 deletions include/emio/detail/format/formatter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ inline constexpr result<void> write_padding_right(writer& out, format_specs& spe
}

template <alignment DefaultAlign, typename Func>
constexpr result<void> write_padded(writer& out, format_specs& specs, size_t width, Func&& func) noexcept {
constexpr result<void> write_padded(writer& out, format_specs& specs, size_t width, const Func& func) noexcept {
if (specs.align == alignment::none) {
specs.align = DefaultAlign;
}
Expand Down Expand Up @@ -705,8 +705,9 @@ inline constexpr result<void> check_integral_specs(const format_specs& specs) no
case 'o':
case 'O':
return success;
default:
return err::invalid_format;
}
return err::invalid_format;
}

inline constexpr result<void> check_unsigned_specs(const format_specs& specs) noexcept {
Expand Down Expand Up @@ -762,8 +763,9 @@ inline constexpr result<void> check_floating_point_specs(const format_specs& spe
// case 'a': Not supported yet.
// case 'A':
return success;
default:
return err::invalid_format;
}
return err::invalid_format;
}

inline constexpr result<void> check_string_specs(const format_specs& specs) noexcept {
Expand All @@ -785,8 +787,8 @@ inline constexpr bool has_formatter_v = std::is_constructible_v<formatter<Arg>>;

template <typename T>
concept has_validate_function_v = requires {
{ formatter<T>::validate(std::declval<reader&>()) } -> std::same_as<result<void>>;
};
{ formatter<T>::validate(std::declval<reader&>()) } -> std::same_as<result<void>>;
};

template <typename T>
concept has_any_validate_function_v =
Expand Down
42 changes: 19 additions & 23 deletions include/emio/detail/format/ranges.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ concept advanceable = requires(T x) { ++x; };

template <typename T>
concept is_iterable = std::is_array_v<T> || requires(T x) {
{ begin(x) } -> advanceable;
requires !std::is_same_v<decltype(*begin(x)), void>;
{ static_cast<bool>(begin(x) != end(x)) };
};
{ begin(x) } -> advanceable;
requires !std::is_same_v<decltype(*begin(x)), void>;
{ static_cast<bool>(begin(x) != end(x)) };
};

template <typename T>
using element_type_t = std::remove_cvref_t<decltype(*begin(std::declval<std::remove_reference_t<T>&>()))>;
Expand All @@ -46,8 +46,7 @@ template <typename T>
concept is_string_like = std::is_constructible_v<std::string_view, T>;

template <typename T>
concept is_valid_range = is_iterable<T> && !
is_string_like<T>&& is_formattable_v<element_type_t<T>>;
concept is_valid_range = is_iterable<T> && !is_string_like<T> && is_formattable_v<element_type_t<T>>;

template <typename T>
struct is_span : std::false_type {};
Expand All @@ -56,12 +55,11 @@ template <typename T, size_t N>
struct is_span<std::span<T, N>> : std::true_type {};

template <typename T>
concept is_contiguous_but_not_span =
std::is_array_v<T> || requires(T x) {
requires !is_span<T>::value;
requires std::is_same_v<std::remove_cvref_t<decltype(*data(x))>, element_type_t<T>>;
{ size(x) } -> std::same_as<size_t>;
};
concept is_contiguous_but_not_span = std::is_array_v<T> || requires(T x) {
requires !is_span<T>::value;
requires std::is_same_v<std::remove_cvref_t<decltype(*data(x))>, element_type_t<T>>;
{ size(x) } -> std::same_as<size_t>;
};

struct ranges_specs {
std::string_view opening_bracket{};
Expand All @@ -85,31 +83,29 @@ using std::get;
// From https://stackoverflow.com/a/68444475/1611317
template <class T, std::size_t N>
concept has_tuple_element = requires(T t) {
typename std::tuple_element_t<N, std::remove_const_t<T>>;
{ get<N>(t) } -> std::convertible_to<const std::tuple_element_t<N, T>&>;
};
typename std::tuple_element_t<N, std::remove_const_t<T>>;
{ get<N>(t) } -> std::convertible_to<const std::tuple_element_t<N, T>&>;
};

template <typename T, size_t... Ns>
constexpr auto has_tuple_element_unpack(std::index_sequence<Ns...> /*unused*/) noexcept {
return (has_tuple_element<T, Ns> && ...);
}

template <class T>
concept is_tuple_like = !
std::is_reference_v<T>&& requires(T t) {
typename std::tuple_size<T>::type;
requires std::derived_from<std::tuple_size<T>,
std::integral_constant<std::size_t, std::tuple_size_v<T>>>;
} && has_tuple_element_unpack<T>(std::make_index_sequence<std::tuple_size_v<T>>());
concept is_tuple_like = !std::is_reference_v<T> && requires(T t) {
typename std::tuple_size<T>::type;
requires std::derived_from<std::tuple_size<T>, std::integral_constant<std::size_t, std::tuple_size_v<T>>>;
} && has_tuple_element_unpack<T>(std::make_index_sequence<std::tuple_size_v<T>>());

template <typename T, size_t... Ns>
constexpr auto is_formattable_unpack(std::index_sequence<Ns...> /*unused*/) noexcept {
return (is_formattable_v<decltype(get<Ns>(std::declval<T&>()))> && ...);
}

template <typename T>
concept is_valid_tuple = !
is_valid_range<T>&& is_tuple_like<T>&& is_formattable_unpack<T>(std::make_index_sequence<std::tuple_size_v<T>>());
concept is_valid_tuple = !is_valid_range<T> && is_tuple_like<T> &&
is_formattable_unpack<T>(std::make_index_sequence<std::tuple_size_v<T>>());

template <typename T, std::size_t... Ns>
auto get_tuple_formatters(std::index_sequence<Ns...> /*unused*/)
Expand Down
12 changes: 7 additions & 5 deletions include/emio/detail/scan/scanner.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,10 @@ inline constexpr int get_base(char type) noexcept {
return 10;
case 'x':
return 16;
default:
EMIO_Z_DEV_ASSERT(false);
EMIO_Z_INTERNAL_UNREACHABLE;
}
EMIO_Z_DEV_ASSERT(false);
EMIO_Z_INTERNAL_UNREACHABLE;
}

inline constexpr result<void> parse_alternate_form(reader& in, int base) noexcept {
Expand Down Expand Up @@ -305,8 +306,9 @@ inline constexpr result<void> check_integral_specs(const format_specs& specs) no
case 'o':
case 'x':
return success;
default:
return err::invalid_format;
}
return err::invalid_format;
}

inline constexpr result<void> check_string_specs(const format_specs& specs) noexcept {
Expand All @@ -326,8 +328,8 @@ inline constexpr bool has_scanner_v = std::is_constructible_v<scanner<Arg>>;

template <typename T>
concept has_validate_function_v = requires {
{ scanner<T>::validate(std::declval<reader&>()) } -> std::same_as<result<void>>;
};
{ scanner<T>::validate(std::declval<reader&>()) } -> std::same_as<result<void>>;
};

template <typename T>
concept has_any_validate_function_v =
Expand Down
1 change: 1 addition & 0 deletions include/emio/detail/validated_string.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class runtime_string {
constexpr runtime_string() = default;

// Don't allow temporary strings or any nullptr.
// NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved): as intended
constexpr runtime_string(std::string&&) = delete;
constexpr runtime_string(std::nullptr_t) = delete;
constexpr runtime_string(int) = delete;
Expand Down
Loading

0 comments on commit 265ac25

Please sign in to comment.