1 Star 0 Fork 0

fensnote/cosmos

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
Format.hpp 3.42 KB
一键复制 编辑 原始数据 按行查看 历史
WangXi 提交于 2015-10-27 14:23 . #pragma once
#pragma once
#include <tuple>
#include <type_traits>
#include <string>
#include <inttypes.h>
#include <cctype>
using namespace std;
namespace detail
{
char g_buf[2000] = {};
inline void FormatArg(char*& buf, int i)
{
_itoa(i, buf, 10);
buf += strlen(buf);
}
inline void FormatArg(char*& buf, double i)
{
auto r = sprintf(buf, "%.6f", i);
buf += r;
}
inline void FormatArg(char*& buf, int64_t i)
{
auto r = sprintf(buf, "%"PRId64, i);
buf += r;
}
inline void FormatArg(char*& buf, uint64_t i)
{
auto r = sprintf(buf, "%"PRIu64, i);
buf += r;
}
inline void FormatArg(char*& buf, const char* p)
{
int len = strlen(p);
memcpy(buf, p, len);
buf += len;
}
inline void FormatArg(char*& buf, string& s)
{
memcpy(buf, s.data(), s.size());
buf += s.size();
}
template<size_t k, typename Tuple>
typename std::enable_if < (k == std::tuple_size<Tuple>::value)>::type
inline GetArgByIndex(size_t, Tuple&, char*&)
{
throw std::invalid_argument("arg index out of range");
}
template<size_t k = 0, typename Tuple>
typename std::enable_if < (k < std::tuple_size<Tuple>::value)>::type
inline GetArgByIndex(size_t index, Tuple& tp, char*& p)
{
if (k == index)
{
FormatArg(p, std::get<k>(tp));
}
else
{
GetArgByIndex<k + 1>(index, tp, p);
}
}
inline int GetIndex(char*& p)
{
char temp[3] = {};
int i = 0;
while (*p != '}'&&*p != '\0')
{
if (i >= 2)
throw std::invalid_argument("index is out of range.");
if (std::isdigit(*p))
{
//push digit
temp[i++] = *p;
char next = *(p + 1);
if (std::isdigit(next))
{
temp[i++] = next;
p += 2;
continue;
}
//validate arg
if (!std::isspace(next) && next != '}')
{
throw std::invalid_argument("invalid argument.");
}
}
p++;
}
return i == 0 ? -1 : std::atoi(temp);
}
}
template<typename... Args>
inline string format(const string& src, Args... args)
{
return format((char*) src.c_str(), args...);
}
template<typename... Args>
inline string format(char* src, Args... args)
{
using namespace detail;
char* buf = g_buf;
auto tp = std::tuple<Args...>(args...);
char* p = src;
char* original = p;
int len = strlen(src) + 1;
int last = 0;
  while (true)
{
if (*p == '{')
{
//copy content befor {
last = p - original;
memcpy(buf, original, last);
buf += last;
//format args
int index = GetIndex(p);
if (index >= 0)
{
GetArgByIndex<0>(index, tp, Fun, buf);
}
//skip }
original = p + 1;
}
     else if(*p=='\0')
{        
      last = p - original;
      memcpy(buf, original, last);
break;
     }  
p++;
}
  string s = g_buf;
  memset(g_buf, 0, buf - g_buf);
  return s;
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/fensnote/cosmos.git
git@gitee.com:fensnote/cosmos.git
fensnote
cosmos
cosmos
master

搜索帮助

0d507c66 1850385 C8b1a773 1850385