/
UCS
/
sqlite_orm
Обзор
Документация
Войти
/
UCS
/
sqlite_orm
Код
Запросы
0
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
dev/operators.h
278 строк
8 KB
klaus triendl
Addressed the chicken-and-egg problem with <optional>, <string_view>
28 май 2022, 11:25
28 май 2022, 11:25
231fec9
Код
Авторство
О чём код?
#pragma once #include <type_traits> // std::false_type, std::true_type #include <utility> // std::move #include "functional/cxx_optional.h" #include "tags.h" #include "serialize_result_type.h" namespace sqlite_orm { namespace internal { /** * Inherit this class to support arithmetic types overloading */ struct arithmetic_t {}; template<class L, class R, class... Ds> struct binary_operator : Ds... { using left_type = L; using right_type = R; left_type lhs; right_type rhs; binary_operator(left_type lhs_, right_type rhs_) : lhs(std::move(lhs_)), rhs(std::move(rhs_)) {} }; struct conc_string { serialize_result_type serialize() const { return "||"; } }; /** * Result of concatenation || operator */ template<class L, class R> using conc_t = binary_operator<L, R, conc_string>; struct add_string { serialize_result_type serialize() const { return "+"; } }; /** * Result of addition + operator */ template<class L, class R> using add_t = binary_operator<L, R, add_string, arithmetic_t, negatable_t>; struct sub_string { serialize_result_type serialize() const { return "-"; } }; /** * Result of substitute - operator */ template<class L, class R> using sub_t = binary_operator<L, R, sub_string, arithmetic_t, negatable_t>; struct mul_string { serialize_result_type serialize() const { return "*"; } }; /** * Result of multiply * operator */ template<class L, class R> using mul_t = binary_operator<L, R, mul_string, arithmetic_t, negatable_t>; struct div_string { serialize_result_type serialize() const { return "/"; } }; /** * Result of divide / operator */ template<class L, class R> using div_t = binary_operator<L, R, div_string, arithmetic_t, negatable_t>; struct mod_operator_string { serialize_result_type serialize() const { return "%"; } }; /** * Result of mod % operator */ template<class L, class R> using mod_t = binary_operator<L, R, mod_operator_string, arithmetic_t, negatable_t>; struct bitwise_shift_left_string { serialize_result_type serialize() const { return "<<"; } }; /** * Result of bitwise shift left << operator */ template<class L, class R> using bitwise_shift_left_t = binary_operator<L, R, bitwise_shift_left_string, arithmetic_t, negatable_t>; struct bitwise_shift_right_string { serialize_result_type serialize() const { return ">>"; } }; /** * Result of bitwise shift right >> operator */ template<class L, class R> using bitwise_shift_right_t = binary_operator<L, R, bitwise_shift_right_string, arithmetic_t, negatable_t>; struct bitwise_and_string { serialize_result_type serialize() const { return "&"; } }; /** * Result of bitwise and & operator */ template<class L, class R> using bitwise_and_t = binary_operator<L, R, bitwise_and_string, arithmetic_t, negatable_t>; struct bitwise_or_string { serialize_result_type serialize() const { return "|"; } }; /** * Result of bitwise or | operator */ template<class L, class R> using bitwise_or_t = binary_operator<L, R, bitwise_or_string, arithmetic_t, negatable_t>; struct bitwise_not_string { serialize_result_type serialize() const { return "~"; } }; /** * Result of bitwise not ~ operator */ template<class T> struct bitwise_not_t : bitwise_not_string, arithmetic_t, negatable_t { using argument_type = T; argument_type argument; bitwise_not_t(argument_type argument_) : argument(std::move(argument_)) {} }; struct assign_string { serialize_result_type serialize() const { return "="; } }; /** * Result of assign = operator */ template<class L, class R> using assign_t = binary_operator<L, R, assign_string>; /** * Assign operator traits. Common case */ template<class T> struct is_assign_t : public std::false_type {}; /** * Assign operator traits. Specialized case */ template<class L, class R> struct is_assign_t<assign_t<L, R>> : public std::true_type {}; template<class L, class... Args> struct in_t; } /** * Public interface for || concatenation operator. Example: `select(conc(&User::name, "@gmail.com"));` => SELECT * name || '@gmail.com' FROM users */ template<class L, class R> internal::conc_t<L, R> conc(L l, R r) { return {std::move(l), std::move(r)}; } /** * Public interface for + operator. Example: `select(add(&User::age, 100));` => SELECT age + 100 FROM users */ template<class L, class R> internal::add_t<L, R> add(L l, R r) { return {std::move(l), std::move(r)}; } /** * Public interface for - operator. Example: `select(sub(&User::age, 1));` => SELECT age - 1 FROM users */ template<class L, class R> internal::sub_t<L, R> sub(L l, R r) { return {std::move(l), std::move(r)}; } /** * Public interface for * operator. Example: `select(mul(&User::salary, 2));` => SELECT salary * 2 FROM users */ template<class L, class R> internal::mul_t<L, R> mul(L l, R r) { return {std::move(l), std::move(r)}; } /** * Public interface for / operator. Example: `select(div(&User::salary, 3));` => SELECT salary / 3 FROM users * @note Please notice that ::div function already exists in pure C standard library inside <cstdlib> header. * If you use `using namespace sqlite_orm` directive you an specify which `div` you call explicitly using `::div` or `sqlite_orm::div` statements. */ template<class L, class R> internal::div_t<L, R> div(L l, R r) { return {std::move(l), std::move(r)}; } /** * Public interface for % operator. Example: `select(mod(&User::age, 5));` => SELECT age % 5 FROM users */ template<class L, class R> internal::mod_t<L, R> mod(L l, R r) { return {std::move(l), std::move(r)}; } template<class L, class R> internal::bitwise_shift_left_t<L, R> bitwise_shift_left(L l, R r) { return {std::move(l), std::move(r)}; } template<class L, class R> internal::bitwise_shift_right_t<L, R> bitwise_shift_right(L l, R r) { return {std::move(l), std::move(r)}; } template<class L, class R> internal::bitwise_and_t<L, R> bitwise_and(L l, R r) { return {std::move(l), std::move(r)}; } template<class L, class R> internal::bitwise_or_t<L, R> bitwise_or(L l, R r) { return {std::move(l), std::move(r)}; } template<class T> internal::bitwise_not_t<T> bitwise_not(T t) { return {std::move(t)}; } template<class L, class R> internal::assign_t<L, R> assign(L l, R r) { return {std::move(l), std::move(r)}; } }