cpp-ru / ideas

Идеи по улучшению языка C++ для обсуждения
https://cpp-ru.github.io/proposals
Creative Commons Zero v1.0 Universal
91 stars 0 forks source link

Добавить новое понятие character types: char, char8_t, wchar_t, char16_t, char32_t, ограничить взаимодействие их с другими арифметическими типами #559

Open raidenluikang opened 1 year ago

raidenluikang commented 1 year ago

Предлагаю новое понятие character types и там добавить типы char, wchar_t, char8_t, char16_t, char32_t. Их надо отделять от integral types. И сильно надо ограничить их взаимодействие с другими арифметическими типами. Возможно запредекатит имплисит конвертация другими типы к character types.

char c = 'A'; // OK
std::string s ;
  s = c; // OK

  int i = 'B'; // deprecated, use char, or use static_cast<int>('B');

  s = i; // deprecated, use char or use static_cast<char>(i);

Уже очень надоело такие ошибки.

struct some_param{
      std::string progress;
};
....

void foo(some_param& param){
         param.progress = 100; // Молча компилируется gcc, clang даже с -Wall ,   только в -Wconversion показывает варнинг но это уже слишком много ошибок показывает везде даже в библиотечные коды, что теряется там полезные варнингы.
}
incoder1 commented 1 year ago

Решается концептами весьма просто, кроме ограничений на арифметические типы, Что в общем я пологаю не правильным на этом уровне астракций. Я у себя реализовал в библиотеке вот так https://github.com/incoder1/IO/blob/refactor/libio/include/io/core/type_traits_ext.hpp


#include <type_traits>

template<bool>
struct __conditional {
    template<typename _Tp, typename>
    using type = _Tp;
};

template<>
struct __conditional<false> {
    template<typename, typename _Up>
    using type = _Up;
};

template<bool _Cond, typename _If, typename _Else>
using __conditional_t
    = typename __conditional<_Cond>::template type<_If, _Else>;

template<typename...>
struct __or_;

template<>
struct __or_<>
    : public std::false_type {
};

template<typename _B1>
struct __or_<_B1>
    : public _B1 {
};

template<typename _B1, typename _B2>
struct __or_<_B1, _B2>
    : public __conditional_t<_B1::value, _B1, _B2> {
};

template<typename _B1, typename _B2, typename _B3, typename... _Bn>
struct __or_<_B1, _B2, _B3, _Bn...>
    : public __conditional_t<_B1::value, _B1, __or_<_B2, _B3, _Bn...>> {
};

template<typename _Tp>
using __remove_cv_t = typename std::remove_cv<_Tp>::type;

template<typename _Tp, typename... _Types>
using __is_one_of = __or_<std::is_same<_Tp, _Types>...>;

template<typename _Tp>
using is_charater = __is_one_of<__remove_cv_t<_Tp>,
      char, wchar_t, char16_t, char32_t, char8_t
      >;

template <typename _Tp>
concept is_charater_v = is_charater<_Tp>::value;

Дальше делаем ограничение там где нам нужно, например:


static constexpr const unsigned int BITS = sizeof(unsigned int) * CHAR_BIT;
static constexpr const unsigned int LAT_A = std::char_traits<char32_t>::to_int_type(U'a');
static constexpr const unsigned int ALBT_SIZE = 26;

template<typename char_t>
    requires( is_charater_v<char_t> )
constexpr bool is_alpha(const char_t ch) noexcept
{
    return ( (static_cast<unsigned int>(std::char_traits<char_t>::to_int_type(ch)) | BITS ) - LAT_A) < ALBT_SIZE;
}