Skip to content

Commit

Permalink
Basic C++20 support
Browse files Browse the repository at this point in the history
fix #21
  • Loading branch information
alandefreitas committed May 19, 2022
1 parent 246f783 commit c605357
Show file tree
Hide file tree
Showing 9 changed files with 118 additions and 49 deletions.
4 changes: 2 additions & 2 deletions examples/unicode_strings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ main() {
small::string str = U"Hello 🌎!";

// Accessing bytes
std::cout << str[4] << '\n'; // o
std::cout << str[6] << '\n'; //
std::cout << static_cast<char>(str[4]) << '\n'; // o
std::cout << static_cast<char>(str[6]) << '\n'; //

// Accessing codepoints
using cp_idx = small::string::codepoint_index;
Expand Down
22 changes: 20 additions & 2 deletions include/small/detail/algorithm/utf.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace small {
namespace detail {
/// Set the types for UTF in C++
#ifdef cpp_char8_t
// there's no operator<<(stream, char8_t) in C++20
using utf8_char_type = char8_t;
#else
using utf8_char_type = char;
Expand Down Expand Up @@ -260,7 +261,8 @@ namespace small {
template <class Char32, class Size = size_t, class Result = uint8_t>
constexpr Result
utf32_size(Char32, Size available_code_units = 1) noexcept {
return static_cast<Result>((std::min)(Size(1), available_code_units));
return static_cast<Result>(
(std::min)(Size(1), available_code_units));
}

/// \brief Get size a utf32 char would have when/if converted to utf8
Expand Down Expand Up @@ -738,7 +740,8 @@ namespace small {
source + (std::min)(source_count, dest_count),
dest,
[](auto in) { return static_cast<output_value_type>(in); });
return static_cast<uint8_t>((std::min)(source_count, dest_count));
return static_cast<uint8_t>(
(std::min)(source_count, dest_count));
} else {
return static_cast<uint8_t>(
from_utf8_to_utf16(source, source_count, dest, dest_count));
Expand Down Expand Up @@ -803,7 +806,22 @@ namespace small {
return to_utf8(source, source_count, dest, dest_count);
}
}

} // namespace detail
} // namespace small

#ifdef cpp_char8_t
inline
std::ostream&
operator<<(std::ostream& os, char8_t c) {
return os << static_cast<char>(c);
}

inline
std::ostream&
operator<<(std::ostream& os, const char8_t* c) {
return os << reinterpret_cast<const char*>(c);
}
#endif

#endif // SMALL_DETAIL_ALGORITHM_UTF_HPP
19 changes: 12 additions & 7 deletions include/small/detail/container/lookup_table_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,10 +253,15 @@ namespace small {
/// \section Custom types
using byte_type = std::conditional_t<
IS_CONST_LOOKUP,
const nonstd::span_lite::std17::byte,
nonstd::span_lite::std17::byte>;
const std::byte,
std::byte>;
#if span_USES_STD_SPAN
static constexpr std::size_t dynamic_extent_value
= std::dynamic_extent;
#else
static constexpr nonstd::span_lite::extent_t dynamic_extent_value
= nonstd::span_lite::dynamic_extent;
#endif
using byte_span_type = nonstd::span<byte_type, dynamic_extent_value>;
using string_view_type = std::basic_string_view<CharT, Traits>;

Expand Down Expand Up @@ -1168,19 +1173,19 @@ namespace small {
= last_it.is_at_step_size() ?
entry_size_for(old_size) :
0;
typename byte_span_type::pointer byte_begin_pos
= last_it.span().data() - codepoint_hint_shift;
typename byte_span_type::iterator byte_begin_pos
= last_it.span().begin() - codepoint_hint_shift;
// 1.b) Last byte is after where the first is stored (where
// size storage begins)
typename byte_span_type::pointer byte_end_pos
typename byte_span_type::iterator byte_end_pos
= data_.end() - 1 - old_size_of_size;
// Shift the table entries:
// - left by new_size_of_size - old_size_of_size bytes, or
// - right by old_size_of_size - new_size_of_size bytes
if (new_size_of_size > old_size_of_size) {
const size_type shift_size = old_size_of_size
- new_size_of_size;
typename byte_span_type::pointer new_byte_begin
typename byte_span_type::iterator new_byte_begin
= byte_begin_pos - shift_size;
shift::shift_left(
new_byte_begin,
Expand All @@ -1189,7 +1194,7 @@ namespace small {
} else {
const size_type shift_size = old_size_of_size
- new_size_of_size;
typename byte_span_type::pointer new_byte_end
typename byte_span_type::iterator new_byte_end
= byte_end_pos + shift_size;
shift::shift_right(
byte_begin_pos,
Expand Down
2 changes: 2 additions & 0 deletions include/small/detail/container/span-lite.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,8 @@
namespace nonstd {

using std::span;
using std::as_bytes;
using std::as_writable_bytes;

// Note: C++20 does not provide comparison
// using std::operator==;
Expand Down
12 changes: 9 additions & 3 deletions include/small/detail/iterator/codepoint_iterator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,14 @@ namespace small {
const codepoint_reference_impl &impl) {
if constexpr (not is_utf32_v<value_type>) {
if (impl.size() == 1) {
os << impl.container_->operator[](impl.byte_index_);
os << static_cast<char>(
impl.container_->operator[](impl.byte_index_));
} else {
console_unicode_guard g(os, impl.size(), 1);
os << std::string_view(
impl.container_->data() + impl.byte_index_,
reinterpret_cast<const char *>(
impl.container_->data())
+ impl.byte_index_,
impl.size());
}
} else {
Expand Down Expand Up @@ -234,7 +237,10 @@ namespace small {
// Compare codepoints now
for (size_type i = 0; i < rhs_utf8_size; ++i) {
if (lhs.container_->operator[](lhs.byte_index_ + i)
!= rhs[i]) {
!= static_cast<
typename codepoint_reference_impl::
string_type::value_type>(rhs[i]))
{
return false;
}
}
Expand Down
Loading

0 comments on commit c605357

Please sign in to comment.