8 Star 29 Fork 21

10km / common_source_cpp

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
cast_utilits.h 9.59 KB
一键复制 编辑 原始数据 按行查看 历史
#ifndef COMMON_SOURCE_CPP_CAST_UTILITS_H_
#define COMMON_SOURCE_CPP_CAST_UTILITS_H_
#include <type_traits>
#include <algorithm>
#include <iterator>
#include <memory>
#include <vector>
#include <ctime>
#include <string>
#include <map>
#include <list>
#include <set>
#include <sstream>
#include <chrono>
#include "date_utilits.h"
/** 类型转换模板函数族,实现通用类型L->R的转换 */
namespace net {
namespace gdface {
namespace utils {
// 判断类型是否可以强制转换
template<typename T>
struct is_force_cast : std::integral_constant < bool,std::is_arithmetic<T>::value || std::is_enum<T>::value> {};
// 相同类型直接转发
template<typename L>
void cast(const L &left, L &right) {
right = left;
}
template<typename L>
L
cast(L left, typename std::decay<L>::type *right) {
return std::forward<L>(left);
}
// 数字类型和enum都使用强制类型转换
template<typename L, typename R>
typename std::enable_if < !std::is_same<L, R>::value && is_force_cast<L>::value && is_force_cast<R>::value, void > ::type
cast(L left, R &right) {
right = (R)left;
}
template<typename L, typename R>
typename std::enable_if < !std::is_same<L, R>::value && is_force_cast<L>::value && is_force_cast<R>::value, R > ::type
cast(L left, R*right) {
return (R)left;
}
// number -> string
template<typename L>
typename std::enable_if<std::is_arithmetic<L>::value, void>::type
cast(L left, std::string &right) {
std::ostringstream ss;
ss << left;
right = ss.str();
}
template<typename L>
typename std::enable_if<std::is_arithmetic<L>::value, std::string>::type
cast(L left, std::string *) {
std::string right;
cast(left, right);
return right;
}
// string -> number
template<typename R>
typename std::enable_if<std::is_arithmetic<R>::value, void>::type
cast(const std::string &left, R& r) {
std::istringstream ss(left);
ss >> r;
}
template<typename R>
typename std::enable_if<std::is_arithmetic<R>::value, R>::type
cast(const std::string &left, R *) {
R right;
cast(left, right);
return right;
}
// uint64_t(milliseconds) to tm
void
inline cast(uint64_t left, std::tm&right) {
auto mTime = std::chrono::milliseconds(left);
auto tp = std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>(mTime);
auto tt = std::chrono::system_clock::to_time_t(tp);
right = *std::localtime(&tt);
}
std::tm
inline cast(uint64_t left, std::tm*) {
std::tm right;
cast(left, right);
return right;
}
void
inline cast(const std::tm &left, uint64_t&right) {
auto l = left;
auto time = std::mktime(&l) * 1000;
right = (uint64_t)time;
}
uint64_t
inline cast(const std::tm &left, uint64_t*) {
uint64_t right;
cast(left, right);
return right;
}
// int64_t(milliseconds) to tm
void
inline cast(int64_t left, std::tm&right) {
auto mTime = std::chrono::milliseconds(left);
auto tp = std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>(mTime);
auto tt = std::chrono::system_clock::to_time_t(tp);
right = *std::localtime(&tt);
}
std::tm
inline cast(int64_t left, std::tm*) {
std::tm right;
cast(left, right);
return right;
}
// tm to int64_t(milliseconds)
void
inline cast(const std::tm &left, int64_t&right) {
auto l = left;
time_t time = std::mktime(&l) * 1000;
right = (int64_t)time;
}
int64_t
inline cast(const std::tm &left, int64_t*) {
int64_t right;
cast(left, right);
return right;
}
// time string(ISO8601) to int64_t(milliseconds)
void
inline cast(const std::string& left, int64_t &right) {
date::time_mills mills;
if (date::parse_iso8601(left, mills) || date::parset_datetime(left, mills))
{
right = (int64_t)(mills.time_since_epoch().count());
}
}
int64_t
inline cast(const std::string& left, int64_t*) {
int64_t right;
cast(left, right);
return right;
}
// int64_t(milliseconds) to time string(ISO8601)
void
inline cast(int64_t left, std::string &right) {
right = date::format_iso8601_mills(left);
}
std::string
inline cast(int64_t left, std::string*) {
std::string right;
cast(left, right);
return right;
}
// time string(ISO8601) to std::tm
void
inline cast(const std::string& left, std::tm &right) {
if (!date::parse_iso8601(left, right))
{
date::parset_datetime(left, right);
}
}
std::tm
inline cast(const std::string& left, std::tm*) {
std::tm right;
cast(left, right);
return right;
}
// std::tm to time string(ISO8601)
void
inline cast(const std::tm& left, std::string &right) {
right = date::format_iso8601(left);
}
std::string
inline cast(const std::tm& left, std::string*) {
std::string right;
cast(left, right);
return right;
}
// string --> vector<uint8_t>
void
inline cast(const std::vector<uint8_t> &left, std::string&right) {
right.assign(left.begin(), left.end());
}
std::string
inline cast(const std::vector<uint8_t> &left, std::string*) {
return std::string(left.begin(), left.end());
}
// vector<uint8_t> --> string
void
inline cast(const std::string &left, std::vector<uint8_t>&right) {
right.assign(left.begin(), left.end());
}
std::vector<uint8_t>
inline cast(const std::string &left, std::vector<uint8_t>*) {
return std::vector<uint8_t>(left.begin(),left.end());
}
// list cast
template<typename L, typename R>
typename std::enable_if<!std::is_same<L, R>::value, void>::type
cast(const std::list<L>&left, std::list<R>& right) {
for (auto l : left) {
R r;
cast(l, r);
right.emplace_back(r);
}
}
template<typename L, typename R>
typename std::enable_if<!std::is_same<L, R>::value, std::list<R>>::type
cast(std::list<L>&&left, std::list<R>*) {
std::list<R> right;
std::transform(left.begin(), left.end(), std::back_inserter(right), [](L l)->R {return cast(std::move(l), (R*)nullptr); });
return std::move(right);
}
template<typename L, typename R>
typename std::enable_if<!std::is_same<L, R>::value, std::list<R>>::type
cast(const std::list<L>&left, std::list<R>*) {
std::list<R> right;
cast(left, right);
return std::move(right);
}
// set cast
template<typename L, typename R>
typename std::enable_if<!std::is_same<L, R>::value, void>::type
cast(const std::set<L>&left, std::set<R>&right) {
std::transform(left.begin(), left.end(), std::insert_iterator<std::set<R>>(right, right.begin()), [](L l)->R {return cast(l, (R*)nullptr); });
}
template<typename L, typename R>
typename std::enable_if<!std::is_same<L, R>::value, std::set<R>>::type
cast(std::set<L>&&left, std::set<R>*) {
std::set<R> right;
std::transform(left.begin(), left.end(), std::insert_iterator<std::set<R>>(right, right.begin()), [](L l)->R {return cast(std::move(l), (R*)nullptr); });
return std::move(right);
}
template<typename L, typename R>
typename std::enable_if<!std::is_same<L, R>::value, std::set<R>>::type
cast(const std::set<L>&left, std::set<R>*) {
std::set<R> right;
cast(left, right);
return std::move(right);
}
// vector cast
template<typename L, typename R>
typename std::enable_if<!std::is_same<L, R>::value, void>::type
cast(const std::vector<L>&left, std::vector<R>& right) {
std::transform(left.begin(), left.end(), std::insert_iterator<std::vector<R>>(right, right.begin()), [](L l)->R {return cast(l, (R*)nullptr); });
}
template<typename L, typename R>
typename std::enable_if<!std::is_same<L, R>::value, std::vector<R>>::type
cast(std::vector<L>&&left, std::vector<R>*) {
std::vector<R> right;
std::transform(left.begin(), left.end(), std::insert_iterator<std::vector<R>>(right, right.begin()), [](L l)->R {return cast(std::move(l), (R*)nullptr); });
return std::move(right);
}
template<typename L, typename R>
typename std::enable_if<!std::is_same<L, R>::value, std::vector<R>>::type
cast(const std::vector<L>&left, std::vector<R>*) {
std::vector<R> right;
cast(left, right);
return std::move(right);
}
// map cast
template<typename KL, typename VL, typename KR, typename VR>
typename std::enable_if<!std::is_same<KL, KR>::value || !std::is_same<VL, VR>::value, void>::type
cast(const std::map<KL, VL>&left, std::map<KR, VR>&right) {
std::transform(left.begin(), left.end(), std::insert_iterator<std::map<KR, VR>>(right, right.begin()),
[](std::pair<KL, VL> l)->std::pair<KR, VR> {return std::pair<KR, VR>(cast(l.first, (KR*)nullptr), cast(l.second, (VR*)nullptr)); });
}
template<typename KL, typename VL, typename KR, typename VR>
typename std::enable_if<!std::is_same<KL, KR>::value || !std::is_same<VL, VR>::value, std::map<KR, VR>>::type
cast(std::map<KL, VL>&&left, std::map<KR, VR>*) {
std::map<KR, VR> right;
std::transform(left.begin(), left.end(), std::insert_iterator<std::map<KR, VR>>(right, right.begin()),
[](std::pair<KL, VL> l)->std::pair<KR, VR> {return std::pair<KR, VR>(cast(std::move(l.first), (KR*)nullptr), cast(std::move(l.second), (VR*)nullptr)); });
return std::move(right);
}
template<typename KL, typename VL, typename KR, typename VR>
typename std::enable_if<!std::is_same<KL, KR>::value || !std::is_same<VL, VR>::value, std::map<KR, VR>>::type
cast(const std::map<KL, VL>&left, std::map<KR, VR>*) {
std::map<KR, VR> right;
cast(left, right);
return std::move(right);
}
} /* namespace utils */
} /* namespace gdface */
} /* namespace net */
#endif // !COMMON_SOURCE_CPP_CAST_UTILITS_H_
C++
1
https://gitee.com/l0km/common_source_cpp.git
git@gitee.com:l0km/common_source_cpp.git
l0km
common_source_cpp
common_source_cpp
master

搜索帮助