Date: Thu, 5 Oct 2023 11:48:53 +0100
On Thu, Oct 5, 2023 at 12:06 AM Frederick Virchanza Gotham
<cauldwell.thomas_at_[hidden]> wrote:
>
> So 'easy_string' could be an interface for 'string'.
Here's a nice implementation of easy_string:
https://godbolt.org/z/hh3G6rcdq
And here it is copy-pasted:
#include <string> // string
#include <format> // format
class easy_string : public std::string {
using Base = std::string;
public:
template<typename T>
easy_string &operator+=(T &&arg) // can receive Lvalue-ref or Rvalue-ref
{
typedef std::remove_cvref_t<T> ParamT;
Base *const bsthis = this;
/* More efficient implementation for 3 types: char, std::string, char*
Note that 'char' is distinct from both 'signed char' and
'unsigned char'
(the latter two being treated as numbers rather than characters) */
if constexpr ( std::is_same_v<ParamT, char>
|| std::is_same_v<ParamT, std::string>
|| (std::is_pointer_v<ParamT> && std::is_same_v<
std::remove_cvref_t< std::remove_pointer_t<ParamT> >, char > ) )
{
*bsthis += std::forward<T>(arg);
}
else
{
*bsthis += std::format("{}", std::forward<T>(arg));
}
return *this;
}
template<typename T>
easy_string operator+(T &&arg) // can receive Lvalue-ref or Rvalue-ref
{
return easy_string(*this) += std::forward<T>(arg);
}
};
#include <iostream>
int main(void)
{
std::string bsstr("My name is Frederick and I have ");
easy_string &str = static_cast<easy_string&>(bsstr);
str += 5;
str += " pet axolotls. My favourite number is Pi, which is roughly ";
std::cout << (str + 3.14) << std::endl;
str += 3.13;
std::cout << str << std::endl;
str += ". Also, my favourite letter of the alphabet is ";
str += 'E';
str += ", but that's only because it was the ";
str += static_cast<signed char>(1);
str += "st letter I ever learned.";
std::cout << str << std::endl;
}
We would just need a paragraph in the Standard to say that you can
cast safely from 'string&' to 'easy_string&', and that the
anti-aliasing rules accommodate this.
<cauldwell.thomas_at_[hidden]> wrote:
>
> So 'easy_string' could be an interface for 'string'.
Here's a nice implementation of easy_string:
https://godbolt.org/z/hh3G6rcdq
And here it is copy-pasted:
#include <string> // string
#include <format> // format
class easy_string : public std::string {
using Base = std::string;
public:
template<typename T>
easy_string &operator+=(T &&arg) // can receive Lvalue-ref or Rvalue-ref
{
typedef std::remove_cvref_t<T> ParamT;
Base *const bsthis = this;
/* More efficient implementation for 3 types: char, std::string, char*
Note that 'char' is distinct from both 'signed char' and
'unsigned char'
(the latter two being treated as numbers rather than characters) */
if constexpr ( std::is_same_v<ParamT, char>
|| std::is_same_v<ParamT, std::string>
|| (std::is_pointer_v<ParamT> && std::is_same_v<
std::remove_cvref_t< std::remove_pointer_t<ParamT> >, char > ) )
{
*bsthis += std::forward<T>(arg);
}
else
{
*bsthis += std::format("{}", std::forward<T>(arg));
}
return *this;
}
template<typename T>
easy_string operator+(T &&arg) // can receive Lvalue-ref or Rvalue-ref
{
return easy_string(*this) += std::forward<T>(arg);
}
};
#include <iostream>
int main(void)
{
std::string bsstr("My name is Frederick and I have ");
easy_string &str = static_cast<easy_string&>(bsstr);
str += 5;
str += " pet axolotls. My favourite number is Pi, which is roughly ";
std::cout << (str + 3.14) << std::endl;
str += 3.13;
std::cout << str << std::endl;
str += ". Also, my favourite letter of the alphabet is ";
str += 'E';
str += ", but that's only because it was the ";
str += static_cast<signed char>(1);
str += "st letter I ever learned.";
std::cout << str << std::endl;
}
We would just need a paragraph in the Standard to say that you can
cast safely from 'string&' to 'easy_string&', and that the
anti-aliasing rules accommodate this.
Received on 2023-10-05 10:49:06