Skip to content

Commit

Permalink
Remove workarounds for compilers that didn't implement C++20 concepts
Browse files Browse the repository at this point in the history
  • Loading branch information
randombit committed Feb 16, 2024
1 parent d0b2107 commit 6e427cd
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 110 deletions.
35 changes: 0 additions & 35 deletions src/lib/utils/concepts.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,31 +121,6 @@ inline constexpr void assert_equal_byte_lengths(R0&& r0, Rs&&... rs)

namespace concepts {

// TODO: C++20 use std::convertible_to<> that was not available in Android NDK
// as of this writing. Tested with API Level up to 33.
template <class FromT, class ToT>
concept convertible_to = std::is_convertible_v<FromT, ToT> && requires { static_cast<ToT>(std::declval<FromT>()); };

// TODO: C++20 provides concepts like std::equality_comparable or
// std::three_way_comparable, but at the time of this writing, some
// target platforms did not ship with those (Xcode 14, Android NDK r25,
// emscripten)

template <typename T>
concept equality_comparable = requires(const std::remove_reference_t<T>& a, const std::remove_reference_t<T> b) {
{ a == b } -> convertible_to<bool>;
};

template <typename T>
concept three_way_comparison_result =
convertible_to<T, std::weak_ordering> || convertible_to<T, std::partial_ordering> ||
convertible_to<T, std::strong_ordering>;

template <typename T>
concept three_way_comparable = requires(const std::remove_reference_t<T>& a, const std::remove_reference_t<T> b) {
{ a <=> b } -> three_way_comparison_result;
};

template <class T>
concept destructible = std::is_nothrow_destructible_v<T>;

Expand Down Expand Up @@ -207,16 +182,6 @@ concept strong_type = is_strong_type_v<T>;
template <class T>
concept contiguous_strong_type = strong_type<T> && contiguous_container<T>;

// std::integral is a concept that is shipped with C++20 but Android NDK is not
// yet there.
// TODO: C++20 - replace with std::integral
template <typename T>
concept integral = std::is_integral_v<T>;

// TODO: C++20 - replace with std::unsigned_integral
template <typename T>
concept unsigned_integral = std::is_integral_v<T> && std::is_unsigned_v<T>;

} // namespace concepts

} // namespace Botan
Expand Down
38 changes: 19 additions & 19 deletions src/lib/utils/loadstor.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
#ifndef BOTAN_LOAD_STORE_H_
#define BOTAN_LOAD_STORE_H_

#include <botan/concepts.h>
#include <botan/mem_ops.h>
#include <botan/types.h>
#include <botan/internal/bswap.h>
#include <concepts>
#include <vector>

namespace Botan {
Expand Down Expand Up @@ -88,7 +88,7 @@ inline constexpr uint64_t make_uint64(
* @param in_range a fixed-length span with some bytes
* @return T loaded from in, as a big-endian value
*/
template <concepts::unsigned_integral T, ranges::contiguous_range<uint8_t> InR>
template <std::unsigned_integral T, ranges::contiguous_range<uint8_t> InR>
inline constexpr T load_be(InR&& in_range) {
ranges::assert_exact_byte_length<sizeof(T)>(in_range);
std::span in{in_range};
Expand All @@ -113,7 +113,7 @@ inline constexpr T load_be(InR&& in_range) {
* @param in_range a fixed-length span with some bytes
* @return T loaded from in, as a little-endian value
*/
template <concepts::unsigned_integral T, ranges::contiguous_range<uint8_t> InR>
template <std::unsigned_integral T, ranges::contiguous_range<uint8_t> InR>
inline constexpr T load_le(InR&& in_range) {
ranges::assert_exact_byte_length<sizeof(T)>(in_range);
std::span in{in_range};
Expand Down Expand Up @@ -222,7 +222,7 @@ inline constexpr T load_le(const uint8_t in[], size_t off) {
* @param off an offset into the array
* @return off'th unsigned integer of in, as a big-endian value
*/
template <concepts::unsigned_integral T>
template <std::unsigned_integral T>
inline constexpr T load_be(const uint8_t in[], size_t off) {
// asserts that *in points to the correct amount of memory
return load_be<T>(std::span<const uint8_t, sizeof(T)>(in + off * sizeof(T), sizeof(T)));
Expand All @@ -234,7 +234,7 @@ inline constexpr T load_be(const uint8_t in[], size_t off) {
* @param off an offset into the array
* @return off'th unsigned integer of in, as a little-endian value
*/
template <concepts::unsigned_integral T>
template <std::unsigned_integral T>
inline constexpr T load_le(const uint8_t in[], size_t off) {
// asserts that *in points to the correct amount of memory
return load_le<T>(std::span<const uint8_t, sizeof(T)>(in + off * sizeof(T), sizeof(T)));
Expand All @@ -245,7 +245,7 @@ inline constexpr T load_le(const uint8_t in[], size_t off) {
* @param in a fixed-length span to some bytes
* @param outs a arbitrary-length parameter list of unsigned integers to be loaded
*/
template <ranges::contiguous_range<uint8_t> InR, concepts::unsigned_integral... Ts>
template <ranges::contiguous_range<uint8_t> InR, std::unsigned_integral... Ts>
requires(sizeof...(Ts) > 0) && all_same_v<Ts...>
inline constexpr void load_be(InR&& in, Ts&... outs) {
ranges::assert_exact_byte_length<(sizeof(Ts) + ...)>(in);
Expand All @@ -262,7 +262,7 @@ inline constexpr void load_be(InR&& in, Ts&... outs) {
* @param in a fixed-length span to some bytes
* @param outs a arbitrary-length parameter list of unsigned integers to be loaded
*/
template <ranges::contiguous_range<uint8_t> InR, concepts::unsigned_integral... Ts>
template <ranges::contiguous_range<uint8_t> InR, std::unsigned_integral... Ts>
requires(sizeof...(Ts) > 0) && all_same_v<Ts...>
inline constexpr void load_le(InR&& in, Ts&... outs) {
ranges::assert_exact_byte_length<(sizeof(Ts) + ...)>(in);
Expand All @@ -279,7 +279,7 @@ inline constexpr void load_le(InR&& in, Ts&... outs) {
* @param in a pointer to some bytes
* @param outs a arbitrary-length parameter list of unsigned integers to be loaded
*/
template <concepts::unsigned_integral... Ts>
template <std::unsigned_integral... Ts>
requires(sizeof...(Ts) > 0) && all_same_v<Ts...>
inline constexpr void load_be(const uint8_t in[], Ts&... outs) {
constexpr auto bytes = (sizeof(outs) + ...);
Expand All @@ -292,7 +292,7 @@ inline constexpr void load_be(const uint8_t in[], Ts&... outs) {
* @param in a pointer to some bytes
* @param outs a arbitrary-length parameter list of unsigned integers to be loaded
*/
template <concepts::unsigned_integral... Ts>
template <std::unsigned_integral... Ts>
requires(sizeof...(Ts) > 0) && all_same_v<Ts...>
inline constexpr void load_le(const uint8_t in[], Ts&... outs) {
constexpr auto bytes = (sizeof(outs) + ...);
Expand Down Expand Up @@ -354,7 +354,7 @@ inline constexpr void load_be(T out[], const uint8_t in[], size_t count) {
* @param in the input unsigned integer
* @param out_range the fixed-length span to write to
*/
template <concepts::unsigned_integral T, ranges::contiguous_output_range<uint8_t> OutR>
template <std::unsigned_integral T, ranges::contiguous_output_range<uint8_t> OutR>
inline constexpr void store_be(T in, OutR&& out_range) {
ranges::assert_exact_byte_length<sizeof(T)>(out_range);
std::span out{out_range};
Expand All @@ -379,7 +379,7 @@ inline constexpr void store_be(T in, OutR&& out_range) {
* @param in the input unsigned integer
* @param out_range the fixed-length span to write to
*/
template <concepts::unsigned_integral T, ranges::contiguous_output_range<uint8_t> OutR>
template <std::unsigned_integral T, ranges::contiguous_output_range<uint8_t> OutR>
inline constexpr void store_le(T in, OutR&& out_range) {
ranges::assert_exact_byte_length<sizeof(T)>(out_range);
std::span out{out_range};
Expand All @@ -404,7 +404,7 @@ inline constexpr void store_le(T in, OutR&& out_range) {
* @param in the input unsigned integer
* @param out the byte array to write to
*/
template <concepts::unsigned_integral T>
template <std::unsigned_integral T>
inline constexpr void store_be(T in, uint8_t out[sizeof(T)]) {
store_be(in, std::span<uint8_t, sizeof(T)>(out, sizeof(T)));
}
Expand All @@ -414,7 +414,7 @@ inline constexpr void store_be(T in, uint8_t out[sizeof(T)]) {
* @param in the input unsigned integer
* @param out the byte array to write to
*/
template <concepts::unsigned_integral T>
template <std::unsigned_integral T>
inline constexpr void store_le(T in, uint8_t out[sizeof(T)]) {
store_le(in, std::span<uint8_t, sizeof(T)>(out, sizeof(T)));
}
Expand All @@ -424,7 +424,7 @@ inline constexpr void store_le(T in, uint8_t out[sizeof(T)]) {
* @param out a fixed-length span to some bytes
* @param ins a arbitrary-length parameter list of unsigned integers to be stored
*/
template <ranges::contiguous_output_range<uint8_t> OutR, concepts::unsigned_integral... Ts>
template <ranges::contiguous_output_range<uint8_t> OutR, std::unsigned_integral... Ts>
requires(sizeof...(Ts) > 0) && all_same_v<Ts...>
inline constexpr void store_be(OutR&& out, Ts... ins) {
ranges::assert_exact_byte_length<(sizeof(Ts) + ...)>(out);
Expand All @@ -441,7 +441,7 @@ inline constexpr void store_be(OutR&& out, Ts... ins) {
* @param out a fixed-length span to some bytes
* @param ins a arbitrary-length parameter list of unsigned integers to be stored
*/
template <ranges::contiguous_output_range<uint8_t> OutR, concepts::unsigned_integral... Ts>
template <ranges::contiguous_output_range<uint8_t> OutR, std::unsigned_integral... Ts>
requires(sizeof...(Ts) > 0) && all_same_v<Ts...>
inline constexpr void store_le(OutR&& out, Ts... ins) {
ranges::assert_exact_byte_length<(sizeof(Ts) + ...)>(out);
Expand All @@ -458,7 +458,7 @@ inline constexpr void store_le(OutR&& out, Ts... ins) {
* @param ins a pointer to some bytes to be written
* @param out a arbitrary-length parameter list of unsigned integers to be stored
*/
template <concepts::unsigned_integral... Ts>
template <std::unsigned_integral... Ts>
requires(sizeof...(Ts) > 0) && all_same_v<Ts...>
inline constexpr void store_be(uint8_t out[], Ts... ins) {
constexpr auto bytes = (sizeof(ins) + ...);
Expand All @@ -471,7 +471,7 @@ inline constexpr void store_be(uint8_t out[], Ts... ins) {
* @param ins a pointer to some bytes to be written
* @param out a arbitrary-length parameter list of unsigned integers to be stored
*/
template <concepts::unsigned_integral... Ts>
template <std::unsigned_integral... Ts>
requires(sizeof...(Ts) > 0) && all_same_v<Ts...>
inline constexpr void store_le(uint8_t out[], Ts... ins) {
constexpr auto bytes = (sizeof(ins) + ...);
Expand All @@ -484,7 +484,7 @@ inline constexpr void store_le(uint8_t out[], Ts... ins) {
* @param in the input unsigned integer
* @return a byte array holding the integer value in big-endian byte order
*/
template <concepts::unsigned_integral T>
template <std::unsigned_integral T>
inline constexpr auto store_be(T in) {
std::array<uint8_t, sizeof(T)> out;
store_be(in, out);
Expand All @@ -496,7 +496,7 @@ inline constexpr auto store_be(T in) {
* @param in the input unsigned integer
* @return a byte array holding the integer value in little-endian byte order
*/
template <concepts::unsigned_integral T>
template <std::unsigned_integral T>
inline constexpr auto store_le(T in) {
std::array<uint8_t, sizeof(T)> out;
store_le(in, out);
Expand Down
Loading

0 comments on commit 6e427cd

Please sign in to comment.