| 113 | |
| 114 | template <class TStringType> |
| 115 | class TBasicCharRef { |
| 116 | public: |
| 117 | using TChar = typename TStringType::TChar; |
| 118 | |
| 119 | TBasicCharRef(TStringType& s, size_t pos) |
| 120 | : S_(s) |
| 121 | , Pos_(pos) |
| 122 | { |
| 123 | } |
| 124 | |
| 125 | operator TChar() const { |
| 126 | return S_.at(Pos_); |
| 127 | } |
| 128 | |
| 129 | TChar* operator&() { |
| 130 | return S_.begin() + Pos_; |
| 131 | } |
| 132 | |
| 133 | const TChar* operator&() const { |
| 134 | return S_.cbegin() + Pos_; |
| 135 | } |
| 136 | |
| 137 | TBasicCharRef& operator=(TChar c) { |
| 138 | Y_ASSERT(Pos_ < S_.size() || (Pos_ == S_.size() && !c)); |
| 139 | |
| 140 | S_.Detach()[Pos_] = c; |
| 141 | |
| 142 | return *this; |
| 143 | } |
| 144 | |
| 145 | TBasicCharRef& operator=(const TBasicCharRef& other) { |
| 146 | return this->operator=(static_cast<TChar>(other)); |
| 147 | } |
| 148 | |
| 149 | /* |
| 150 | * WARN: |
| 151 | * Though references are copyable types according to the standard, |
| 152 | * the behavior of this explicit default specification is different from the one |
| 153 | * implemented by the assignment operator above. |
| 154 | * |
| 155 | * An attempt to explicitly delete it will break valid invocations like |
| 156 | * auto c = flag ? s[i] : s[j]; |
| 157 | */ |
| 158 | TBasicCharRef(const TBasicCharRef&) = default; |
| 159 | |
| 160 | private: |
| 161 | TStringType& S_; |
| 162 | size_t Pos_; |
| 163 | }; |
| 164 | |
| 165 | template <typename TCharType, typename TTraits> |
| 166 | class Y_EMPTY_BASES TBasicString: public TStringBase<TBasicString<TCharType, TTraits>, TCharType, TTraits>, |