C++ variable parameter template implements functions similar to C# format

// require c++17
#pragma once

#include <string>

static int replace_all(std::string& string,
                        const std::string_view& replaced_key,
                        const std::string_view& replacing_key)
{
    
    
    if (replaced_key == replacing_key)
        return 0;
    int count                  = 0;
    std::string::size_type pos = 0;
    const size_t predicate     = !replaced_key.empty() ? 0 : 1;
    while ((pos = string.find(replaced_key, pos)) != std::wstring::npos)
    {
    
    
        (void)string.replace(pos, replaced_key.length(), replacing_key);
        pos += (replacing_key.length() + predicate);
        ++count;
    }
    return count;
}

// The placeholder edition of _csfmt_replace
inline void _csfmt_replace(std::string& fmt, int& idx) {
    
    }

template <typename _Arg> inline void _csfmt_replace(std::string& fmt, int& idx, _Arg value)
{
    
    
  char pattern[64];
  sprintf(pattern, "{%d}", idx);
  replace_all(fmt, pattern, std::to_string(value));
  ++idx;
}

template <> inline void _csfmt_replace<const std::string&>(std::string& fmt, int& idx, const std::string& value)
{
    
    
  char pattern[64];
  sprintf(pattern, "{%d}", idx);
  replace_all(fmt, pattern, value);
  ++idx;
}

template <> inline void _csfmt_replace<std::string_view>(std::string& fmt, int& idx, std::string_view value)
{
    
    
  char pattern[64];
  sprintf(pattern, "{%d}", idx);
  replace_all(fmt, pattern, value);
  ++idx;
}

template <> inline void _csfmt_replace<const char*>(std::string& fmt, int& idx, const char* value)
{
    
    
  char pattern[64];
  sprintf(pattern, "{%d}", idx);
  replace_all(fmt, pattern, value);
  ++idx;
}

template <> inline void _csfmt_replace<const void*>(std::string& fmt, int& idx, const void* value)
{
    
    
  char pattern[64];
  char sval[20];
  sprintf(pattern, "{%d}", idx);
  sprintf(sval, "%p", value);
  replace_all(fmt, pattern, sval);
  ++idx;
}

template <typename _Arg0, typename... _Args>
inline void _csfmt_replace(std::string& fmt, int& idx, _Arg0 arg0, _Args&&... args)
{
    
    
  _csfmt_replace(fmt, idx, arg0);
  _csfmt_replace(fmt, idx, std::forward <_Args>(args)...);
}

template <typename... _Args> inline std::string _csfmt(std::string fmt, _Args... args)
{
    
    
  int idx = 0;
  _csfmt_replace(fmt, idx, std::forward <_Args>(args)...);
  return fmt;
}

Guess you like

Origin blog.csdn.net/xyzzf/article/details/129441105