#include <tuple>
#include <iostream>
#include <sstream>
#include <string>
#include <type_traits>
template<typename... T>
decltype(auto) values(T&&... args) {
return std::forward_as_tuple(std::forward<T&&>(args)...);
}
class C_SQL {
public:
template <typename T, typename U>
struct decay_equiv : std::is_same<typename std::decay<T>::type, U>::type
{};
template<size_t I, class TupleType>
void at(const TupleType& tp)
{
using type_t = std::tuple_element<I, TupleType >::type;
if (I > 0) {
sqltext_ << ",";
}
if (decay_equiv<type_t, int>::value) {
sqltext_ << "int";
}
else if (decay_equiv<type_t, float>::value) {
sqltext_ << "float";
}
else if (decay_equiv<type_t, char>::value) {
sqltext_ << "char";
}
if (std::is_rvalue_reference<type_t>::value) {
sqltext_ << "右值=";
}
else {
sqltext_ << "左值=";
}
sqltext_ << std::get<I>(tp);
}
template<class TupleType, size_t... I>
void concat(const TupleType& tp, std::index_sequence<I...>)
{
sqltext_ << "values(";
(..., at<I>(tp));
sqltext_ << ")";
}
template<typename... Args>
C_SQL& operator%(const std::tuple<Args...>& tp) {
concat(tp, std::make_index_sequence<sizeof...(Args)>());
return *this;
}
std::stringstream sqltext_;
};
int main() {
const int x = 1;
C_SQL sql;
sql % values(x, 2.f, '3');
std::cout << sql.sqltext_.str();
}