Skip to content

Commit

Permalink
馃洜 C++17 vetting!
Browse files Browse the repository at this point in the history
- 馃敤 More contiguous iterator checks, including snooping into both MSVC and GCC's iterator types!
  • Loading branch information
ThePhD committed Jul 2, 2021
1 parent 87404d5 commit 00ef86b
Show file tree
Hide file tree
Showing 13 changed files with 87 additions and 33 deletions.
7 changes: 3 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ if (ZTD_TEXT_IS_TOP_LEVEL_PROJECT)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/x64/${CMAKE_BUILD_TYPE}/${CFG_INT_DIR}/bin")
endif()

if (NOT CMAKE_CXX_STANDARD GREATER_EQUAL 20)
set(CMAKE_CXX_STANDARD 20)
if (NOT DEFINED CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 17)
endif()

if (NOT CMAKE_C_STANDARD GREATER_EQUAL 11)
if (NOT DEFINED CMAKE_CXX_STANDARD)
set(CMAKE_C_STANDARD 11)
endif()

Expand Down Expand Up @@ -195,5 +195,4 @@ if (ZTD_TEXT_SCRATCH)
${--warn-pedantic}
${--warn-all}
${--warn-errors})
target_compile_features(scratch PRIVATE cxx_std_20)
endif()
14 changes: 12 additions & 2 deletions include/ztd/text/counted_iterator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,23 @@ namespace ztd { namespace text {

template <typename _It2, ::std::enable_if_t<::std::is_convertible_v<_It2, iterator_type>>* = nullptr>
constexpr __counted_iterator(const __counted_iterator<_It2>& __from) noexcept(
::std::is_nothrow_convertible_v<const _It2&, iterator_type>)
#if ZTD_TEXT_IS_ON(ZTD_TEXT_STD_LIBRARY_IS_NOTHROW_CONVERTIBLE_I_)
::std::is_nothrow_convertible_v<const _It2&, iterator_type>
#else
noexcept(static_cast<iterator_type>(::std::declval<const _It2&>()))
#endif
)
: _M_count(__from._M_count), _M_it(__from._M_it) {
}

template <typename _It2, ::std::enable_if_t<::std::is_convertible_v<_It2, iterator_type>>* = nullptr>
constexpr __counted_iterator(__counted_iterator<_It2>&& __from) noexcept(
::std::is_nothrow_convertible_v<_It2&&, iterator_type>)
#if ZTD_TEXT_IS_ON(ZTD_TEXT_STD_LIBRARY_IS_NOTHROW_CONVERTIBLE_I_)
::std::is_nothrow_convertible_v<_It2&&, iterator_type>
#else
noexcept(static_cast<iterator_type>(::std::declval<_It2&&>()))
#endif
)
: _M_count(::std::move(__from._M_count)), _M_it(::std::move(__from._M_it)) {
}

Expand Down
6 changes: 3 additions & 3 deletions include/ztd/text/detail/byte_iterator.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 Down Expand Up @@ -89,13 +89,13 @@ namespace ztd { namespace text {
}

__byte_reference& operator=(value_type __val) {
const __base_value_type __shift = __ones_mask_to_shift<__base_value_type>(this->_M_mask);
const __base_value_type __shift = __ones_mask_to_right_shift<__base_value_type>(this->_M_mask);
this->M_ref |= static_cast<__base_value_type>(__val) << __shift;
return *this;
}

value_type value() const {
const mask_type __shift = __ones_mask_to_shift<mask_type>(this->_M_mask);
const mask_type __shift = __ones_mask_to_right_shift<mask_type>(this->_M_mask);
return static_cast<value_type>((this->_M_ref & this->_M_mask) >> __shift);
}

Expand Down
2 changes: 1 addition & 1 deletion include/ztd/text/detail/iterator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ namespace ztd { namespace text {
= ::std::is_base_of_v<_Tag, __iterator_concept_t<_It>>;

template <typename _It>
inline constexpr bool __is_iterator_contiguous_iterator_v = __mark_contiguous<_It>::value
inline constexpr bool __is_iterator_contiguous_iterator_v = __mark_contiguous_v<_It>
|| (
#if ZTD_TEXT_IS_ON(ZTD_TEXT_STD_LIBRARY_CONTIGUOUS_ITERATOR_TAG_I_)
__is_iterator_concept_or_better_v<contiguous_iterator_tag, _It>)
Expand Down
18 changes: 13 additions & 5 deletions include/ztd/text/detail/mark_contiguous.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,7 @@

#include <ztd/text/version.hpp>

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

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

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

Expand All @@ -46,14 +44,24 @@ namespace ztd { namespace text {

namespace __txt_detail {

template <typename _It>
struct __mark_contiguous : public ::std::integral_constant<bool, ::std::is_pointer_v<_It>> { };
template <typename _It, typename = void>
struct __mark_contiguous : public ::std::integral_constant<bool, ::std::is_pointer_v<__remove_cvref_t<_It>>> {
};

#if ZTD_TEXT_IS_ON(ZTD_TEXT_LIBSTDCXX_I_)
template <typename _It, typename _Parent>
struct __mark_contiguous<::__gnu_cxx::__normal_iterator<_It, _Parent>> : public __mark_contiguous<_It> { };
#endif

#if ZTD_TEXT_IS_ON(ZTD_TEXT_LIBVCXX_I_)
template <typename _It>
struct __mark_contiguous<_It, ::std::void_t<decltype(::std::declval<_It>()._Unwrapped())>>
: public __mark_contiguous<decltype(::std::declval<_It>()._Unwrapped())> { };
#endif

template <typename _It>
inline constexpr bool __mark_contiguous_v = __mark_contiguous<_It>::value;

} // namespace __txt_detail

ZTD_TEXT_INLINE_ABI_NAMESPACE_CLOSE_I_
Expand Down
16 changes: 13 additions & 3 deletions include/ztd/text/detail/memory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <ztd/text/version.hpp>

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

#include <memory>

Expand Down Expand Up @@ -107,11 +108,20 @@ namespace ztd { namespace text {

template <typename _Pointer, ::std::enable_if_t<!::std::is_pointer_v<_Pointer>>* = nullptr>
auto __adl_to_address(_Pointer& p) noexcept {
if constexpr (__is_detected_v<__detect_std_pointer_traits_to_address, _Pointer>) {
return ::std::pointer_traits<_Pointer>::to_address(p);
if constexpr (__mark_contiguous_v<_Pointer>) {
#if ZTD_TEXT_IS_ON(ZTD_TEXT_LIBVCXX_I_)
return __adl_to_address(p._Unwrapped());
#else
return __adl_to_address(p.operator->());
#endif
}
else {
return __adl_to_address(p.operator->());
if constexpr (__is_detected_v<__detect_std_pointer_traits_to_address, _Pointer>) {
return ::std::pointer_traits<_Pointer>::to_address(p);
}
else {
return __adl_to_address(p.operator->());
}
}
}
#endif
Expand Down
4 changes: 2 additions & 2 deletions include/ztd/text/detail/transcode_one.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ namespace ztd { namespace text {
return __encoding.decode_one(
::std::forward<_Input>(__input), __output_range, __error_handler, __state);
}
else if (
else if constexpr (
(!__is_range_contiguous_range_v<_UOutput> || __is_range_input_or_output_range_v<_UOutput>)&&__is_decode_range_category_contiguous_v<
_UEncoding>) {
code_point_t<_UEncoding> __intermediate_output_storage[max_code_points_v<_UEncoding>];
Expand Down Expand Up @@ -137,7 +137,7 @@ namespace ztd { namespace text {
return __encoding.encode_one(
::std::forward<_Input>(__input), __output_range, __error_handler, __state);
}
else if (
else if constexpr (
(!__is_range_contiguous_range_v<_UOutput> || __is_range_input_or_output_range_v<_UOutput>)&&__is_encode_range_category_contiguous_v<
_UEncoding>) {
constexpr ::std::size_t _IntermediateMax = max_code_units_v<_UEncoding>;
Expand Down
3 changes: 1 addition & 2 deletions include/ztd/text/reconstruct.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,7 @@ namespace ztd {
__adl::__adl_begin(__input), __adl::__adl_end(__input));
}
else {
using _Ty = ::std::remove_extent_t<_VInput>;
return __reconstruct(::std::in_place_type<::ztd::text::span<_Ty>>,
return __reconstruct(::std::in_place_type<::ztd::text::span<_CharTy>>,
__adl::__adl_begin(__input), __adl::__adl_end(__input));
}
}
Expand Down
7 changes: 6 additions & 1 deletion include/ztd/text/subrange.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,12 @@ namespace ztd { namespace text {
template <__subrange_kind _Dummy = _Kind,
::std::enable_if_t<_Dummy == __subrange_kind::sized>* = nullptr>
constexpr size_type size() const noexcept {
return ::std::distance(this->_M_it, this->_M_sen);
if constexpr (_SizeRequired) {
return this->__base_size_t::_M_size;
}
else {
return ::std::distance(this->_M_it, this->_M_sen);
}
}

//////
Expand Down
12 changes: 12 additions & 0 deletions include/ztd/text/version.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,18 @@
#define ZTD_TEXT_STD_LIBRARY_CONTIGUOUS_ITERATOR_TAG_I_ ZTD_TEXT_DEFAULT_OFF
#endif

#if defined(ZTD_TEXT_STD_LIBRARY_IS_NOTHROW_CONVERTIBLE)
#if (ZTD_TEXT_STD_LIBRARY_IS_NOTHROW_CONVERTIBLE != 0)
#define ZTD_TEXT_STD_LIBRARY_IS_NOTHROW_CONVERTIBLE_I_ ZTD_TEXT_ON
#else
#define ZTD_TEXT_STD_LIBRARY_IS_NOTHROW_CONVERTIBLE_I_ ZTD_TEXT_OFF
#endif
#elif defined(__cpp_lib_is_nothrow_convertible)
#define ZTD_TEXT_STD_LIBRARY_IS_NOTHROW_CONVERTIBLE_I_ ZTD_TEXT_DEFAULT_ON
#else
#define ZTD_TEXT_STD_LIBRARY_IS_NOTHROW_CONVERTIBLE_I_ ZTD_TEXT_DEFAULT_OFF
#endif

#if defined(ZTD_TEXT_COMPILE_TIME_ENCODING_NAME)
#define ZTD_TEXT_COMPILE_TIME_ENCODING_NAME_GET_I_() ZTD_TEXT_COMPILE_TIME_ENCODING_NAME
#define ZTD_TEXT_COMPILE_TIME_ENCODING_NAME_DESCRIPTION_I_() "set by the user with ZTD_TEXT_COMPILE_TIME_ENCODING_NAME as (" ZTD_TEXT_TOKEN_TO_STRING_I_(ZTD_TEXT_COMPILE_TIME_ENCODING_NAME) ")"
Expand Down
4 changes: 2 additions & 2 deletions tests/basic_run_time/source/errors.throw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ inline namespace ztd_text_tests_basic_run_time_errors_throw {
using state = ztd::text::decode_state_t<Encoding>;

auto action = [&]() noexcept(false) {
code_point output_buffer[output_max] {};
code_point output_buffer[ztd::text::max_code_points_v<Encoding>] {};
ztd::text::span<const code_unit> input(container.data(), container.size());
ztd::text::span<code_point> output(output_buffer, output_max);
state s {};
Expand All @@ -61,7 +61,7 @@ inline namespace ztd_text_tests_basic_run_time_errors_throw {
using state = ztd::text::encode_state_t<Encoding>;

auto action = [&]() noexcept(false) {
code_unit output_buffer[output_max] {};
code_unit output_buffer[ztd::text::max_code_units_v<Encoding>] {};
ztd::text::span<const code_point> input(container.data(), container.size());
ztd::text::span<code_unit> output(output_buffer, output_max);
state s {};
Expand Down
10 changes: 6 additions & 4 deletions tests/basic_run_time/source/transcode.containers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@
inline namespace ztd_text_tests_transcode_containers {
template <typename FromEncoding, typename ToEncoding, template <class...> typename Container = std::vector>
void check_container_roundtrip(FromEncoding& from_encoding, ToEncoding& to_encoding) {
constexpr bool DecodeInjective = ztd::text::is_decode_injective_v<FromEncoding>;
constexpr bool EncodeInjective = ztd::text::is_encode_injective_v<ToEncoding>;
using ToCodeUnit = ztd::text::code_unit_t<ToEncoding>;
using FromCodeUnit = ztd::text::code_unit_t<FromEncoding>;
#define DecodeInjective ztd::text::is_decode_injective_v<FromEncoding>
#define EncodeInjective ztd::text::is_encode_injective_v<ToEncoding>
using ToCodeUnit = ztd::text::code_unit_t<ToEncoding>;
using FromCodeUnit = ztd::text::code_unit_t<FromEncoding>;
{
Container<FromCodeUnit> in_container = { (FromCodeUnit)0, (FromCodeUnit)0, (FromCodeUnit)0 };
Container<ToCodeUnit> out_container = { (ToCodeUnit)0, (ToCodeUnit)0, (ToCodeUnit)0 };
Expand Down Expand Up @@ -97,6 +97,8 @@ inline namespace ztd_text_tests_transcode_containers {
REQUIRE(
std::equal(std::begin(in_container), std::end(in_container), std::begin(result), std::end(result)));
}
#undef DecodeInjective
#undef EncodeInjective
}
} // namespace ztd_text_tests_transcode_containers

Expand Down
17 changes: 13 additions & 4 deletions tests/shared/include/ztd/text/tests/basic_unicode_strings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1639,8 +1639,9 @@ namespace ztd { namespace text { namespace tests {

inline constexpr const std::basic_string_view<char32_t> u32_unicode_replacement_truth = U"\uFFFD";
inline constexpr const std::basic_string_view<char16_t> u16_unicode_replacement_truth = u"\uFFFD";
inline constexpr const ztd::text::uchar8_t u8_unicode_replacement_truth_storage[] = { 0xEF, 0xBF, 0xBD, 0 };
inline constexpr const std::basic_string_view<ztd::text::uchar8_t> u8_unicode_replacement_truth
= (const ztd::text::uchar8_t*)u8"\uFFFD";
= u8_unicode_replacement_truth_storage;
inline constexpr const std::basic_string_view<wchar_t> w_unicode_replacement_truth = L"?";
inline constexpr const std::basic_string_view<char> unicode_replacement_truth = "?";

Expand All @@ -1665,6 +1666,7 @@ namespace ztd { namespace text { namespace tests {
std::copy(std::begin(bscs), std::end(bscs) - 1, arr.begin());
return arr;
}
#if ZTD_TEXT_IS_ON(ZTD_TEXT_NATIVE_CHAR8_T_I_)
else if constexpr (std::is_same_v<Char, char8_t>) {
const auto& bscs
= u8"\f\v\t "
Expand All @@ -1674,6 +1676,7 @@ namespace ztd { namespace text { namespace tests {
std::copy(std::begin(bscs), std::end(bscs) - 1, arr.begin());
return arr;
}
#endif
else if constexpr (std::is_same_v<Char, ztd::text::uchar8_t>) {
const auto& bscs
= u8"\f\v\t "
Expand Down Expand Up @@ -1733,10 +1736,16 @@ namespace ztd { namespace text { namespace tests {
u"\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_{}[]#()<>%:;.?*+-/^&|~!=,\\\"'\0",
u16_basic_source_character_set_size);
inline constexpr const std::size_t u8_basic_source_character_set_size = 97;
inline constexpr const ztd::text::uchar8_t u8_basic_source_character_set_storage[]
#if ZTD_TEXT_IS_ON(ZTD_TEXT_NATIVE_CHAR8_T_I_)
= u8"\f\v\t "
u8"\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_{}[]#()<>%:;.?*+-/^&|~!=,\\\"'\0";
#else
= "\f\v\t "
"\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_{}[]#()<>%:;.?*+-/^&|~!=,\\\"'\0";
#endif
inline constexpr const std::basic_string_view<ztd::text::uchar8_t> u8_basic_source_character_set(
u8"\f\v\t "
u8"\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_{}[]#()<>%:;.?*+-/^&|~!=,\\\"'\0",
u8_basic_source_character_set_size);
u8_basic_source_character_set_storage, u8_basic_source_character_set_size);
inline constexpr const std::size_t w_basic_source_character_set_size = 97;
inline constexpr const std::basic_string_view<wchar_t> w_basic_source_character_set(
L"\f\v\t "
Expand Down

0 comments on commit 00ef86b

Please sign in to comment.