Skip to content

Commit

Permalink
🧝‍♂️ Proper casting!
Browse files Browse the repository at this point in the history
- Prevent use of char8_t all over the place too
  • Loading branch information
ThePhD committed Feb 22, 2021
1 parent 472a880 commit e1c1bcb
Show file tree
Hide file tree
Showing 15 changed files with 272 additions and 132 deletions.
48 changes: 48 additions & 0 deletions include/ztd/text/any_encoding.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,30 @@ namespace ztd { namespace text {
: _M_state(__encoding._M_storage->__create_decode_state()) {
}

//////
/// @brief You cannot copy construct an any_decode_state.
///
//////
any_decode_state(const any_decode_state&) = delete;

//////
/// @brief You cannot copy assign an any_decode_state.
///
//////
any_decode_state& operator=(const any_decode_state&) = delete;

//////
/// @brief Move constructs an any_decode_state.
///
//////
any_decode_state(any_decode_state&&) = default;

//////
/// @brief Move assigns an any_decode_state.
///
//////
any_decode_state& operator=(any_decode_state&&) = default;

__erased_state* _M_get_erased_state() const noexcept {
return _M_state.get();
}
Expand All @@ -263,6 +287,30 @@ namespace ztd { namespace text {
: _M_state(__encoding._M_storage->__create_encode_state()) {
}

//////
/// @brief You cannot copy construct an any_encode_state.
///
//////
any_encode_state(const any_encode_state&) = delete;

//////
/// @brief You cannot copy assign an any_encode_state.
///
//////
any_encode_state& operator=(const any_encode_state&) = delete;

//////
/// @brief Move constructs an any_encode_state.
///
//////
any_encode_state(any_encode_state&&) = default;

//////
/// @brief Move assigns an any_encode_state.
///
//////
any_encode_state& operator=(any_encode_state&&) = default;

__erased_state* _M_get_erased_state() const noexcept {
return _M_state.get();
}
Expand Down
3 changes: 2 additions & 1 deletion include/ztd/text/decode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ namespace ztd { namespace text {
for (;;) {
// Ignore "out of output" errors and do our best to recover properly along the way...
_Output __intermediate_initial_output(__intermediate_translation_buffer);
auto __result = decode_into(::std::forward<_Input>(__input), ::std::forward<_Encoding>(__encoding),
auto __result = decode_into(::std::move(__working_input), ::std::forward<_Encoding>(__encoding),
__intermediate_initial_output, ::std::forward<_ErrorHandler>(__error_handler), __state);
::ztd::text::span<_IntermediateValueType> __intermediate_output(
__intermediate_initial_output.data(), __result.output.data());
Expand All @@ -226,6 +226,7 @@ namespace ztd { namespace text {
}
if (__result.error_code == encoding_error::insufficient_output_space) {
// loop around, we've got S P A C E for more
__working_input = ::std::move(__result.input);
continue;
}
if (__result.error_code != encoding_error::ok) {
Expand Down
71 changes: 71 additions & 0 deletions include/ztd/text/detail/cast.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@




// =============================================================================
//
// ztd.text
// Copyright © 2021 JeanHeyd "ThePhD" Meneide and Shepherd's Oasis, LLC
// Contact: opensource@soasis.org
//
// Commercial License Usage
// Licensees holding valid commercial ztd.text licenses may use this file in
// accordance with the commercial license agreement provided with the
// Software or, alternatively, in accordance with the terms contained in
// a written agreement between you and Shepherd's Oasis, LLC.
// For licensing terms and conditions see your agreement. For
// further information contact opensource@soasis.org.
//
// Apache License Version 2 Usage
// Alternatively, this file may be used under the terms of Apache License
// Version 2.0 (the "License") for non-commercial use; you may not use this
// file except in compliance with the License. You may obtain a copy of the
// License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// ============================================================================>

#pragma once

#ifndef ZTD_TEXT_DETAIL_CAST_HPP
#define ZTD_TEXT_DETAIL_CAST_HPP

#include <ztd/text/version.hpp>

#include <ztd/text/detail/type_traits.hpp>

#include <utility>

namespace ztd { namespace text {
ZTD_TEXT_INLINE_ABI_NAMESPACE_OPEN_I_
namespace __detail {
enum class __match_alignment { no, yes };

template <typename _To, __match_alignment __require_aligned = __match_alignment::no, typename _From>
constexpr decltype(auto) static_cast_if_lossless(_From&& __from) {
if constexpr ((sizeof(__remove_cvref_t<_To>) == sizeof(__remove_cvref_t<_From>))
&& ((__require_aligned == __match_alignment::no)
|| (alignof(__remove_cvref_t<_To>) == alignof(__remove_cvref_t<_From>)))) {
// explicitly cast, since we know it's of the same size/alignment
// (e.g., unsigned char -> std::byte should work, but it requires a cast!)
return static_cast<_To>(__from);
}
else {
// let it warn/error for weird conversions
// (e.g., short -> char8_t should give a narrowing conversion warning)
return ::std::forward<_From>(__from);
}
}
} // namespace __detail

ZTD_TEXT_INLINE_ABI_NAMESPACE_CLOSE_I_
}} // namespace ztd::text

#endif // ZTD_TEXT_DETAIL_CAST_HPP
68 changes: 34 additions & 34 deletions include/ztd/text/detail/empty_string.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// Apache License Version 2 Usage
// Alternatively, this file may be used under the terms of Apache License
// Version 2.0 (the "License") for non-commercial use; you may not use this
// file except in compliance with the License. You may obtain a copy of the
// file except in compliance with the License. You may obtain a copy of the
// License at
//
// http://www.apache.org/licenses/LICENSE-2.0
Expand All @@ -41,48 +41,48 @@
namespace ztd { namespace text {
ZTD_TEXT_INLINE_ABI_NAMESPACE_OPEN_I_
namespace __detail {
#ifdef __cpp_char8_t
#else
using __arr8_one_t = char8_t[1];
inline constexpr const __arr8_one_t __u8_shim = {};
#if ZTD_TEXT_IS_OFF(ZTD_TEXT_NATIVE_CHAR8_T_I_)
using __arr8_one_t = char8_t[1];
inline constexpr const __arr8_one_t __u8_shim = {};
#endif

template <typename C>
inline constexpr decltype(auto) __empty_string() noexcept {
static_assert(__always_false_v<C>, "unrecognized character type");
return "";
}
template <typename C>
inline constexpr decltype(auto) __empty_string() noexcept {
static_assert(__always_false_v<C>, "unrecognized character type");
return "";
}

template <>
inline constexpr decltype(auto) __empty_string<char>() noexcept {
return "";
}
template <>
inline constexpr decltype(auto) __empty_string<char>() noexcept {
return "";
}

template <>
inline constexpr decltype(auto) __empty_string<wchar_t>() noexcept {
return L"";
}
template <>
inline constexpr decltype(auto) __empty_string<wchar_t>() noexcept {
return L"";
}

template <>
inline constexpr decltype(auto) __empty_string<char8_t>() noexcept {
#ifdef __cpp_char8_t
return u8"";
template <>
inline constexpr decltype(auto) __empty_string<uchar8_t>() noexcept {
#if ZTD_TEXT_IS_OFF(ZTD_TEXT_NATIVE_CHAR8_T_I_)
return (__u8_shim);
#else
return (__u8_shim);
return u8"";
#endif
}
}

template <>
inline constexpr decltype(auto) __empty_string<char16_t>() noexcept {
return u"";
}
template <>
inline constexpr decltype(auto) __empty_string<char16_t>() noexcept {
return u"";
}

template <>
inline constexpr decltype(auto) __empty_string<char32_t>() noexcept {
return U"";
}
template <>
inline constexpr decltype(auto) __empty_string<char32_t>() noexcept {
return U"";
}

}ZTD_TEXT_INLINE_ABI_NAMESPACE_CLOSE_I_
}} // namespace ztd::text::__detail
} // namespace __detail
ZTD_TEXT_INLINE_ABI_NAMESPACE_CLOSE_I_
}} // namespace ztd::text

#endif // ZTD_TEXT_DETAIL_EMPTY_STRING_HPP
8 changes: 4 additions & 4 deletions include/ztd/text/detail/progress_handler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ namespace ztd { namespace text {

template <typename _Encoding, typename _InputRange, typename _OutputRange, typename _State,
typename _Progress>
constexpr auto operator()(const _Encoding& __encoding,
encode_result<_InputRange, _OutputRange, _State> __result, const _Progress& __progress) noexcept {
constexpr auto operator()(const _Encoding&, encode_result<_InputRange, _OutputRange, _State> __result,
const _Progress& __progress) noexcept {
_M_code_points_size = __adl::__adl_size(__progress);
// avoid needing potentially non-constexpr ::std::copy
#ifdef __cpp_lib_constexpr_algorithms
Expand All @@ -82,8 +82,8 @@ namespace ztd { namespace text {

template <typename _Encoding, typename _InputRange, typename _OutputRange, typename _State,
typename _Progress>
constexpr auto operator()(const _Encoding& __encoding,
decode_result<_InputRange, _OutputRange, _State> __result, const _Progress& __progress) noexcept {
constexpr auto operator()(const _Encoding&, decode_result<_InputRange, _OutputRange, _State> __result,
const _Progress& __progress) noexcept {
_M_code_units_size = __adl::__adl_size(__progress);
#ifdef __cpp_lib_constexpr_algorithms
::std::copy_n(__adl::__adl_cbegin(__progress), this->_M_code_units_size,
Expand Down
8 changes: 4 additions & 4 deletions include/ztd/text/detail/transcode_one.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -537,8 +537,8 @@ namespace ztd { namespace text {
auto __intermediate_result = __basic_decode_one<__consume::__no>(::std::forward<_Input>(__input),
::std::forward<_Encoding>(__encoding), __output, ::std::forward<_ErrorHandler>(__error_handler),
__state);
::std::size_t __written
= __adl::__adl_cbegin(__intermediate_result.output) - __adl::__adl_cbegin(__output);
::std::size_t __written = static_cast<::std::size_t>(
__adl::__adl_cbegin(__intermediate_result.output) - __adl::__adl_cbegin(__output));

return _Result(::std::move(__intermediate_result.input), __written, __intermediate_result.state);
}
Expand Down Expand Up @@ -566,8 +566,8 @@ namespace ztd { namespace text {
auto __intermediate_result = __basic_encode_one<__consume::__no>(::std::forward<_Input>(__input),
::std::forward<_Encoding>(__encoding), __output, ::std::forward<_ErrorHandler>(__error_handler),
__state);
::std::size_t __written
= __adl::__adl_cbegin(__intermediate_result.output) - __adl::__adl_cbegin(__output);
::std::size_t __written = static_cast<::std::size_t>(
__adl::__adl_cbegin(__intermediate_result.output) - __adl::__adl_cbegin(__output));

return _Result(::std::move(__intermediate_result.input), __written, __intermediate_result.state);
}
Expand Down
62 changes: 31 additions & 31 deletions include/ztd/text/detail/unicode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,35 +71,35 @@ namespace ztd { namespace text {
inline constexpr char32_t __last_5byte_value = 0x3FFFFFF;
inline constexpr char32_t __last_6byte_value = 0x7FFFFFFF;

inline constexpr char8_t __start_1byte_mask = 0x80u;
inline constexpr char8_t __start_1byte_continuation = 0x00u;
inline constexpr char8_t __start_1byte_shift = 7u;
inline constexpr char8_t __start_2byte_mask = 0xC0u;
inline constexpr char8_t __start_2byte_continuation = __start_2byte_mask;
inline constexpr char8_t __start_2byte_shift = 5u;
inline constexpr char8_t __start_3byte_mask = 0xE0u;
inline constexpr char8_t __start_3byte_continuation = __start_3byte_mask;
inline constexpr char8_t __start_3byte_shift = 4u;
inline constexpr char8_t __start_4byte_mask = 0xF0u;
inline constexpr char8_t __start_4byte_continuation = __start_4byte_mask;
inline constexpr char8_t __start_4byte_shift = 3u;
inline constexpr char8_t __start_5byte_mask = 0xF8u;
inline constexpr char8_t __start_5byte_continuation = __start_5byte_mask;
inline constexpr char8_t __start_5byte_shift = 2u;
inline constexpr char8_t __start_6byte_mask = 0xFCu;
inline constexpr char8_t __start_6byte_continuation = __start_6byte_mask;
inline constexpr char8_t __start_6byte_shift = 1u;

inline constexpr char8_t __continuation_mask = 0xC0u;
inline constexpr char8_t __continuation_signature = 0x80u;
inline constexpr char8_t __continuation_mask_value = 0x3Fu;
inline constexpr char8_t __single_mask_value = 0x7Fu;

inline constexpr bool __utf8_is_invalid(char8_t __b) noexcept {
inline constexpr uchar8_t __start_1byte_mask = 0x80u;
inline constexpr uchar8_t __start_1byte_continuation = 0x00u;
inline constexpr uchar8_t __start_1byte_shift = 7u;
inline constexpr uchar8_t __start_2byte_mask = 0xC0u;
inline constexpr uchar8_t __start_2byte_continuation = __start_2byte_mask;
inline constexpr uchar8_t __start_2byte_shift = 5u;
inline constexpr uchar8_t __start_3byte_mask = 0xE0u;
inline constexpr uchar8_t __start_3byte_continuation = __start_3byte_mask;
inline constexpr uchar8_t __start_3byte_shift = 4u;
inline constexpr uchar8_t __start_4byte_mask = 0xF0u;
inline constexpr uchar8_t __start_4byte_continuation = __start_4byte_mask;
inline constexpr uchar8_t __start_4byte_shift = 3u;
inline constexpr uchar8_t __start_5byte_mask = 0xF8u;
inline constexpr uchar8_t __start_5byte_continuation = __start_5byte_mask;
inline constexpr uchar8_t __start_5byte_shift = 2u;
inline constexpr uchar8_t __start_6byte_mask = 0xFCu;
inline constexpr uchar8_t __start_6byte_continuation = __start_6byte_mask;
inline constexpr uchar8_t __start_6byte_shift = 1u;

inline constexpr uchar8_t __continuation_mask = 0xC0u;
inline constexpr uchar8_t __continuation_signature = 0x80u;
inline constexpr uchar8_t __continuation_mask_value = 0x3Fu;
inline constexpr uchar8_t __single_mask_value = 0x7Fu;

inline constexpr bool __utf8_is_invalid(uchar8_t __b) noexcept {
return __b == 0xC0 || __b == 0xC1 || __b > 0xF4;
}

inline constexpr bool __utf8_is_continuation(char8_t __value) noexcept {
inline constexpr bool __utf8_is_continuation(uchar8_t __value) noexcept {
return (__value & __continuation_mask) == __continuation_signature;
}

Expand Down Expand Up @@ -139,14 +139,14 @@ namespace ztd { namespace text {
return 8;
}

inline constexpr int __sequence_length(char8_t __value) noexcept {
inline constexpr int __sequence_length(uchar8_t __value) noexcept {
return (__value & __start_1byte_mask) == __start_1byte_continuation ? 1
: (__value & __start_3byte_mask) != __start_3byte_continuation ? 2
: (__value & __start_4byte_mask) != __start_4byte_continuation ? 3
: 4;
}

inline constexpr int __sequence_length_extended(char8_t __value) noexcept {
inline constexpr int __sequence_length_extended(uchar8_t __value) noexcept {
return (__value & __start_1byte_mask) == __start_1byte_continuation ? 1
: (__value & __start_3byte_mask) != __start_3byte_continuation ? 2
: (__value & __start_4byte_mask) != __start_4byte_continuation ? 3
Expand All @@ -155,16 +155,16 @@ namespace ztd { namespace text {
: 6;
}

inline constexpr char32_t __decode(char8_t __value0, char8_t __value1) noexcept {
inline constexpr char32_t __decode(uchar8_t __value0, uchar8_t __value1) noexcept {
return static_cast<char32_t>(((__value0 & 0x1F) << 6) | (__value1 & 0x3F));
}

inline constexpr char32_t __decode(char8_t __value0, char8_t __value1, char8_t __value2) noexcept {
inline constexpr char32_t __decode(uchar8_t __value0, uchar8_t __value1, uchar8_t __value2) noexcept {
return static_cast<char32_t>(((__value0 & 0x0F) << 12) | ((__value1 & 0x3F) << 6) | (__value2 & 0x3F));
}

inline constexpr char32_t __decode(
char8_t __value0, char8_t __value1, char8_t __value2, char8_t __value3) noexcept {
uchar8_t __value0, uchar8_t __value1, uchar8_t __value2, uchar8_t __value3) noexcept {
return static_cast<char32_t>(((__value0 & 0x07) << 18) | ((__value1 & 0x3F) << 12)
| ((__value2 & 0x3F) << 6) | (__value3 & 0x3F));
}
Expand Down

0 comments on commit e1c1bcb

Please sign in to comment.