Свой быстрый класс string, вопросы по оптимизации скорости

Создал свой класс string. Цель создания своего класса строк - это скорость работы со строками и второе в образовательных целях. Если реализация получится удачной сделаю библиотеку для личного использования. new и delete решил не использовать, так как использую простой тип char.Прошу просмотреть код и дать рекомендации по оптимизации. Исправлю уже данные замечания и выложу повторно. За ранее благодарю за ответы.

#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <locale.h>
#include <malloc.h>

namespace str
{ 
struct string
{
private:
#pragma region ========================== Variable ==============================
    typedef struct 
    { 
        char *p_str; 
        size_t length;
    }stringA;

    stringA str{};
    const type_info& ti_c = typeid(const_cast<const char * >(str.p_str));

#pragma endregion 

#pragma region ========================== Private Function ==============================
_inline void clr()
{
    if(str.p_str)           free(str.p_str);    
    str.p_str = nullptr;    str.length = 0U;  
}
//------------------------------------------------------------------
_inline bool __type_c(const type_info& ti){return ti_c == ti;}

#pragma endregion 


public:

#pragma region ==================================== Constructor ======================================
/* Конструктор однобайтовые символы */
string(const char *p_str)
{   
    clr();

   // if(p_str){
        if((str.length = strnlen_s(p_str, SIZE_MAX) ) > 0U)
        { 
            if(str.p_str  = static_cast<char *>(malloc(sizeof(char) * (str.length + 1) ) ) ) 
            {
                strncpy_s(str.p_str, str.length + 1, p_str, _TRUNCATE); 
                str.p_str[str.length] = '\0'; 
                
            }
        }else{  str.p_str   = static_cast<char *>       (calloc(1, sizeof(char) ) );}
                
   // }
}
//------------------------------------------------------------------

/* Конструктор по умолчанию */
explicit string(){     
    clr();
    str.p_str   = static_cast<char *>       (calloc(1, sizeof(char) ) ); 
}

//------------------------------------------------------------------
/* Конструктор копирования */
string(const string& s) 
{
   // if(s.c_str() == ""){  str.p_str   = static_cast<char *>       (calloc(1, sizeof(char) ) );}else{

    clr();

    if ((str.length = strnlen_s(s.c_str(), SIZE_MAX)) > 0U) {
        if ((str.p_str = static_cast<char *>    (malloc(sizeof(char) * (str.length + 1) ) ) ) != nullptr) {
    
                strncpy_s(str.p_str, str.length + 1, s.c_str(), _TRUNCATE);
                str.p_str[str.length] = '\0';    
         }
     }
    //}     
}
 
//------------------------------------------------------------------
/* Конструктор перемещения */
string(string &&moved)  noexcept  // ссылка rvalue       
{
    str.p_str = moved.str.p_str;   
    str.length = moved.str.length;
    moved.str.p_str = nullptr;
     
  //  if(str.p_str == nullptr){  str.p_str   = static_cast<char *>       (calloc(1, sizeof(char) ) ); str.length=0U;}
}

//------------------------------------------------------------------
~string(){  clr();  }

#pragma endregion

#pragma region ====================================== Class Members =======================================
//------------------------------------------------------------------
_inline size_t length() const { return str.length ; }

//------------------------------------------------------------------
_inline size_t string_size() const  {   
       return (str.p_str == nullptr) ? 0U : ((str.length +  1) * sizeof(char));    
}

//------------------------------------------------------------------
/* Добавляем строку с реолакацией памяти */
void add(const char *p_str_in)
{   
    size_t l = 0U;
   // if(str.p_str == nullptr) return;    
   
    if ((l = strnlen_s(p_str_in, SIZE_MAX)) != 0U) {
        if ((str.p_str = static_cast<char *> (realloc(str.p_str, (str.length + l + 1) * sizeof(char) ) ) ) != nullptr) {
            
            if(!strcat_s(str.p_str, str.length + l + 1, p_str_in)) str.length += l;
            str.p_str[str.length] = '\0';
        }//else{  str.p_str   = static_cast<char *>       (calloc(1, sizeof(char) ) ); str.length=0U;}
    }
}

//------------------------------------------------------------------
_inline const char* c_str() const {
    return ((str.p_str != nullptr) ? str.p_str : const_cast< char * >(""));
}

//------------------------------------------------------------------
/* Вывести символ в строке по индексу от нуля до str.length - 1 */
_inline char ch_at(size_t index) const  {
        return (/*(str.p_str != nullptr) && */(index < str.length)) ? str.p_str[index] : '\0';
}

//------------------------------------------------------------------
/* Заменить символ встроке по индексу от нуля до str.length - 1 */
_inline void ch_set_at(size_t index, char ch)   {
            if(/*(str.p_str != nullptr) && */(index < str.length))  str.p_str[index] = ch;
}
//------------------------------------------------------------------
_inline void clear(){ str.p_str   = static_cast<char *>       (calloc(1, sizeof(char) ) ); str.length = 0U;}


#pragma endregion

#pragma region ====================================== Operator Reload ============================================
//------------------------------------------------------------------
 string& operator +=(string const &s )  {      
            this->add(const_cast<char *>(s.c_str()));
            return  *this;
}

//------------------------------------------------------------------
  string& operator +=(char *s )    {      
        this->add(static_cast<char *>(s));  
        return  *this;
}

//------------------------------------------------------------------
const auto& operator = (const string& s)
{      
   // if (s.c_str() == "")return this;
    clr();
    if ((str.length = strnlen_s(s.c_str(), SIZE_MAX)) != 0U) {
        if ((str.p_str = static_cast<char *>(malloc(sizeof(char) * (str.length + 1) ) ) ) != nullptr) {
    
                strncpy_s(str.p_str, str.length + 1, s.c_str(), _TRUNCATE);
                str.p_str[str.length] = '\0'; 
         }
     }                  
return this;

}

#pragma endregion

//------------------------------------------------------------------ 
 friend std::ostream &operator <<(std::ostream &ostr, string const &point) { ostr << point.c_str(); return ostr; }

/* Конец string  */
};

//------------------------------------------------------------------
const string operator + (const string &L, const string &R){ return string(L) += R;}    

/* Конец области str:: */
};

//===============================================================================================================================

Вот самая последняя версия класса с нетерпением жду рекомендаций.

#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <locale.h>
#include <malloc.h>

#include <cassert>

namespace str
{

#ifndef SIZE
constexpr   size_t SIZE_STRING = 260 ; /* символов */
#else
constexpr   size_t SIZE_STRING = SIZE ;
#if (SIZE < 260)
constexpr   bool STACK_STRING = true ; /* Возможно для маленьких строк сделаю на стеке */
#else
constexpr   bool STACK_STRING = false ;
#endif
#endif


class string
{

//------------------------------------------------------------------
private:

    size_t leng;        /* Количество символов в строке */
    size_t size_str;    /* Размер выделенной памяти для строки */     
    char *p_str;        /* Строка */
//------------------------------------------------------------------
void clr()
{
    if(p_str != nullptr)    free(p_str);    
    p_str = nullptr;        size_str = leng = 0U;  
}
//------------------------------------------------------------------
auto realloc_foo(size_t &len)
{
        char *p_str_t = nullptr;
        if (len == leng)return p_str;
        /* Где то тут проверка будет нужно пере выделять или нет */
        if ((p_str_t = static_cast<char *> (realloc(p_str, (leng + len + 1) * sizeof(char)))) != nullptr) {

            p_str = p_str_t; p_str_t = nullptr; 
            
        }else{ /* Что делать в этом месте в случае неудачи? */ }
        return p_str;
        
}

//------------------------------------------------------------------
auto malloc_foo(size_t &len)
{   
        /* Тут будет реализация буфера size_str от SIZE_STRING, 
            чтобы избежать лишнего выделения, если len > size_str и SIZE_STRING выделяем len в противном либо SIZE_STRING либо оставляем без изменений  */
        char *p_str_t = nullptr;
        if ((p_str_t = static_cast<char *>(malloc(sizeof(char) * (len + 1) ) ) ) != nullptr) {
                p_str = p_str_t; p_str_t = nullptr; 


         }else{ /* Что делать в этом месте в случае неудачи? */ }
         return p_str;
}

//------------------------------------------------------------------
void construct(const char *pstr) {

        assert(pstr != nullptr);  
   
        if((leng = strnlen_s(pstr, SIZE_MAX) ) > 0U) { 
                strncpy_s(malloc_foo(leng), leng + 1, pstr, _TRUNCATE);             
        }
}
//------------------------------------------------------------------
public:

/* Конструктор однобайтовые символы */
string(const char *pstr)  : leng(0U), size_str(0U), p_str(nullptr) { construct(pstr); }    
   

//------------------------------------------------------------------

/* Конструктор по умолчанию */
string() : leng(0U), size_str(0U), p_str(nullptr) { 

    p_str   = static_cast<char *>       (calloc(SIZE_STRING, sizeof(char) ) );     
}

//------------------------------------------------------------------
/* Конструктор копирования */
string(const string& s) { construct(s.c_str()); }

//------------------------------------------------------------------
/* Конструктор перемещения */
string(string &&moved)   noexcept  : leng(0U), size_str(0U), p_str(nullptr)  // ссылка rvalue       
{  

            clr();              
            p_str = moved.p_str;   
            leng = moved.leng;
            moved.p_str = nullptr;
            moved.leng = 0U;  
}

//------------------------------------------------------------------
~string(){  clr();  }

//------------------------------------------------------------------
size_t length() const { return leng ; }

//------------------------------------------------------------------
size_t string_size() const  {   
       return (p_str == nullptr) ? 0U : ((leng +  1) * sizeof(char));    
}

//------------------------------------------------------------------
/* Добавляем строку с реоллакацией памяти */
void add(const char *p_str_in)
{       
  
    size_t l = 0U;
     assert(p_str_in != nullptr);
    //if(p_str == nullptr) return;  

    if ((l = strnlen_s(p_str_in, SIZE_MAX)) != 0U) {        
         if(!strcat_s(realloc_foo(l), leng + l + 1, p_str_in)) leng += l;
         p_str[leng] = '\0';
    }
}

//------------------------------------------------------------------
const char* c_str() const {
    return ((p_str != nullptr) ? p_str : const_cast< char * >(""));
}

//------------------------------------------------------------------
/* Вывести символ в строке по индексу от нуля до str.length - 1 */
char ch_at(size_t index) const  {
        return ((p_str != nullptr) && (index < leng)) ? p_str[index] : '\0';
}

//------------------------------------------------------------------
/* Заменить символ встроке по индексу от нуля до str.length - 1 */
void ch_set_at(size_t index, char ch)   {
            if((p_str != nullptr) && (index < leng))  p_str[index] = ch;
}
//------------------------------------------------------------------
void clear(){ p_str   = static_cast<char *>       (calloc(SIZE_STRING, sizeof(char) ) ); leng = 0U;}

//------------------------------------------------------------------
 string& operator +=(string const &s )  {      
            this->add(const_cast<char *>(s.c_str()));
            return  *this;
}

//------------------------------------------------------------------
  string& operator +=(const char *s )    {      
        this->add(const_cast<char *>(s));  
        return  *this;
}

//------------------------------------------------------------------
auto & operator = (const string & s) {            
        string tmp(s); swap (*this, tmp);           
        return *this;
}
//------------------------------------------------------------------
auto& operator=(string&& moved)   noexcept {
        swap (*this, moved); return *this;     
}
//------------------------------------------------------------------ 
    auto& operator[] (const size_t index){ assert(index < leng); return p_str[index]; }
    const auto& operator[] (const size_t index) const{assert(index < leng); return p_str[index]; }


//------------------------------------------------------------------ 
 friend std::ostream &operator <<(std::ostream &ostr, string const &point) { ostr << point.c_str(); return ostr; }

 friend void swap (string &l, string &r)
    {
        
        std::swap (l.p_str , r.p_str);
        std::swap (l.leng , r.leng);
        std::swap (l.size_str , r.size_str);
    }

 friend bool operator < (const string& l, const string& r)noexcept
{
  // реализация
}
 
friend bool operator == (const string& l, const string& r)noexcept
{
   //реализация
}


/* Конец string  */
};

//------------------------------------------------------------------

inline const string operator + (const string &L, const string &R){  return string(L) += R;}   


/* Конец области str:: */
};

//=

Ответы (0 шт):