Skip to content

Commit

Permalink
create
Browse files Browse the repository at this point in the history
  • Loading branch information
merlin82 committed Jul 5, 2014
1 parent aff1ec0 commit e19992f
Show file tree
Hide file tree
Showing 5 changed files with 199 additions and 0 deletions.
59 changes: 59 additions & 0 deletions FormatString.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#include "FormatString.h"
#include <time.h>
#include <iomanip>

void _formatTime(std::ostringstream &ss, time_t t)
{
struct tm tm1;
char szTime[24];
#ifdef _WIN32
localtime_s(&tm1, &t);
sprintf_s(szTime, 24, "%04d-%02d-%02d %02d:%02d:%02d",
tm1.tm_year + 1900, tm1.tm_mon + 1, tm1.tm_mday,
tm1.tm_hour, tm1.tm_min, tm1.tm_sec);
#else
localtime_r(&t, &tm1);
snprintf(szTime, 24, "%04d-%02d-%02d %02d:%02d:%02d",
tm1.tm_year + 1900, tm1.tm_mon + 1, tm1.tm_mday,
tm1.tm_hour, tm1.tm_min, tm1.tm_sec);
#endif

ss << szTime;
}

void _formatItem(std::ostringstream &ss, const std::string& item, const CArgArray& args)
{
//{ index[,alignment][ :formatString] }
int index = 0;
int alignment = 0;
std::string fmt;

char* endptr = NULL;
index = strtol(&item[0], &endptr, 10);
if (index < 0 || index >= args.size())
{
return;
}

if (*endptr == ',')
{
alignment = strtol(endptr + 1, &endptr, 10);
if (alignment > 0)
{
ss << std::right << std::setw(alignment);
}
else if (alignment < 0)
{
ss << std::left << std::setw(-alignment);
}
}
if (*endptr == ':')
{
fmt = endptr + 1;
}

args[index]->format(ss, fmt);
return;
}


125 changes: 125 additions & 0 deletions FormatString.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#ifndef _CS_FORMAT_H
#define _CS_FORMAT_H

#include <string>
#include <vector>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#include <sstream>

class CArgArray;
void _formatItem(std::ostringstream &ss, const std::string& item, const CArgArray& args);
void _formatTime(std::ostringstream &ss, time_t t);

class CArgBase
{
public:
CArgBase() {}
virtual ~CArgBase() {}
virtual void format(std::ostringstream &ss, const std::string& fmt) = 0;
};

template <class T>
class CArg : public CArgBase
{
public:
CArg(T arg) :_arg(arg) {}
virtual ~CArg(){}
virtual void format(std::ostringstream &ss, const std::string& fmt)
{
ss << _arg;
}
private:
T _arg;
};

//a example of extension
template <>
class CArg<time_t> : public CArgBase
{
public:
CArg(time_t arg) : _arg(arg) {}
virtual void format(std::ostringstream &ss, const std::string& fmt)
{
if (fmt[0] == 'T')
{
_formatTime(ss, _arg);
}
else
{
ss << _arg;
}
}
private:
time_t _arg;
};

class CArgArray : public std::vector<CArgBase*>
{
public:
CArgArray() {}
~CArgArray()
{
std::for_each(begin(), end(), [](CArgBase* p){delete p; });
}
};

template <class T>
static void transfer(CArgArray& argArray, T t)
{
CArgBase* arg = new CArg<T>(t);
argArray.push_back(arg);
}

template <class T, typename... Args>
static void transfer(CArgArray& argArray, T t, Args... args)
{
transfer(argArray, t);
transfer(argArray, args...);
}

template <typename... Args>
std::string CSFormat(const std::string& format, Args... args)
{
if (sizeof...(args) == 0)
{
return format;
}

CArgArray argArray;
transfer(argArray, args...);
size_t start = 0;
size_t pos = 0;
std::ostringstream ss;
while (true)
{
pos = format.find('{', start);
ss << format.substr(start, pos - start);
if (pos == std::string::npos)
{
break;
}
if (format[pos + 1] == '{')
{
ss << '{';
start = pos + 2;
continue;
}
start = pos + 1;
pos = format.find('}', start);
if (pos == std::string::npos)
{
ss << format.substr(start-1);
break;
}

_formatItem(ss, format.substr(start, pos - start), argArray);

start = pos + 1;
}

return ss.str();
}

#endif
3 changes: 3 additions & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
CSFormat is available for use under the following license

==============================
The MIT License (MIT)

Copyright (c) 2014 merlin fang
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Usage
#include "FormatString.h"
#include <string>
#include <iostream>
#include <time.h>
using namespace std;
int main()
{
Expand Down
11 changes: 11 additions & 0 deletions demo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include "FormatString.h"
#include <string>
#include <iostream>
#include <time.h>
using namespace std;
int main()
{
string demo = CSFormat("{0,20}|{1,-10}|{2}|{3,30:T}|", 11, "aaa", 3.14, time(NULL));
cout << demo << endl;
return 0;
}

0 comments on commit e19992f

Please sign in to comment.