mirror of
https://github.com/rbock/sqlpp11.git
synced 2026-01-01 10:41:22 -06:00
Removed superfluous template parameter from interpreter
The Db parameter would actually have prevented different Context overloads (or made more difficult than necessary).
This commit is contained in:
@@ -80,16 +80,16 @@ namespace sqlpp
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Db, typename... Args>
|
||||
struct interpreter_t<Db, column_t<Args...>>
|
||||
template<typename Context, typename... Args>
|
||||
struct interpreter_t<Context, column_t<Args...>>
|
||||
{
|
||||
using T = column_t<Args...>;
|
||||
template<typename Context>
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << T::_table::_name_t::_get_name() << '.' << T::_name_t::_get_name();
|
||||
return context;
|
||||
}
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << T::_table::_name_t::_get_name() << '.' << T::_name_t::_get_name();
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -74,18 +74,18 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
//FIXME: Write partial specialization for mysql
|
||||
template<typename Db, typename First, typename... Args>
|
||||
struct interpreter_t<Db, concat_t<First, Args...>>
|
||||
template<typename Context, typename First, typename... Args>
|
||||
struct interpreter_t<Context, concat_t<First, Args...>>
|
||||
{
|
||||
using T = concat_t<First, Args...>;
|
||||
template<typename Context>
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
interpret_tuple(t._args, "||", context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
interpret_tuple(t._args, "||", context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -41,122 +41,126 @@ namespace sqlpp
|
||||
struct text;
|
||||
}
|
||||
|
||||
struct boolean_operand
|
||||
struct boolean_operand
|
||||
{
|
||||
static constexpr bool _is_expression = true;
|
||||
using _value_type = detail::boolean;
|
||||
|
||||
bool _is_trivial() const { return _t == false; }
|
||||
|
||||
bool _t;
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct interpreter_t<Context, boolean_operand>
|
||||
{
|
||||
static constexpr bool _is_expression = true;
|
||||
using _value_type = detail::boolean;
|
||||
using Operand = boolean_operand;
|
||||
|
||||
bool _is_trivial() const { return _t == false; }
|
||||
|
||||
bool _t;
|
||||
static Context& _(const Operand& t, Context& context)
|
||||
{
|
||||
context << t._t;
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Db>
|
||||
struct interpreter_t<Db, boolean_operand>
|
||||
template<typename T>
|
||||
struct integral_operand
|
||||
{
|
||||
static constexpr bool _is_expression = true;
|
||||
using _value_type = detail::integral;
|
||||
|
||||
bool _is_trivial() const { return _t == 0; }
|
||||
|
||||
T _t;
|
||||
};
|
||||
|
||||
template<typename Context, typename T>
|
||||
struct interpreter_t<Context, integral_operand<T>>
|
||||
{
|
||||
using Operand = integral_operand<T>;
|
||||
|
||||
static Context& _(const Operand& t, Context& context)
|
||||
{
|
||||
using Operand = boolean_operand;
|
||||
template<typename Context>
|
||||
static void _(const Operand& t, Context& context)
|
||||
{
|
||||
context << t._t;
|
||||
}
|
||||
};
|
||||
context << t._t;
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct integral_operand
|
||||
|
||||
template<typename T>
|
||||
struct floating_point_operand
|
||||
{
|
||||
static constexpr bool _is_expression = true;
|
||||
using _value_type = detail::floating_point;
|
||||
|
||||
bool _is_trivial() const { return _t == 0; }
|
||||
|
||||
T _t;
|
||||
};
|
||||
|
||||
template<typename Context, typename T>
|
||||
struct interpreter_t<Context, floating_point_operand<T>>
|
||||
{
|
||||
using Operand = floating_point_operand<T>;
|
||||
|
||||
static Context& _(const Operand& t, Context& context)
|
||||
{
|
||||
static constexpr bool _is_expression = true;
|
||||
using _value_type = detail::integral;
|
||||
context << t._t;
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
bool _is_trivial() const { return _t == 0; }
|
||||
struct text_operand
|
||||
{
|
||||
static constexpr bool _is_expression = true;
|
||||
using _value_type = detail::text;
|
||||
|
||||
T _t;
|
||||
};
|
||||
bool _is_trivial() const { return _t.empty(); }
|
||||
|
||||
template<typename Db, typename T>
|
||||
struct interpreter_t<Db, integral_operand<T>>
|
||||
std::string _t;
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct interpreter_t<Context, text_operand>
|
||||
{
|
||||
using Operand = text_operand;
|
||||
|
||||
static Context& _(const Operand& t, Context& context)
|
||||
{
|
||||
using Operand = integral_operand<T>;
|
||||
template<typename Context>
|
||||
static void _(const Operand& t, Context& context)
|
||||
{
|
||||
context << t._t;
|
||||
}
|
||||
};
|
||||
context << '\'' << context.escape(t._t) << '\'';
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, typename Enable = void>
|
||||
struct wrap_operand
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct floating_point_operand
|
||||
{
|
||||
static constexpr bool _is_expression = true;
|
||||
using _value_type = detail::floating_point;
|
||||
template<>
|
||||
struct wrap_operand<bool, void>
|
||||
{
|
||||
using type = boolean_operand;
|
||||
};
|
||||
|
||||
bool _is_trivial() const { return _t == 0; }
|
||||
template<typename T>
|
||||
struct wrap_operand<T, typename std::enable_if<std::is_integral<T>::value>::type>
|
||||
{
|
||||
using type = integral_operand<T>;
|
||||
};
|
||||
|
||||
T _t;
|
||||
};
|
||||
template<typename T>
|
||||
struct wrap_operand<T, typename std::enable_if<std::is_floating_point<T>::value>::type>
|
||||
{
|
||||
using type = floating_point_operand<T>;
|
||||
};
|
||||
|
||||
template<typename Db, typename T>
|
||||
struct interpreter_t<Db, floating_point_operand<T>>
|
||||
{
|
||||
using Operand = floating_point_operand<T>;
|
||||
template<typename Context>
|
||||
static void _(const Operand& t, Context& context)
|
||||
{
|
||||
context << t._t;
|
||||
}
|
||||
};
|
||||
|
||||
struct text_operand
|
||||
{
|
||||
static constexpr bool _is_expression = true;
|
||||
using _value_type = detail::text;
|
||||
|
||||
bool _is_trivial() const { return _t.empty(); }
|
||||
|
||||
std::string _t;
|
||||
};
|
||||
|
||||
template<typename Db>
|
||||
struct interpreter_t<Db, text_operand>
|
||||
{
|
||||
using Operand = text_operand;
|
||||
template<typename Context>
|
||||
static void _(const Operand& t, Context& context)
|
||||
{
|
||||
context << '\'' << context.escape(t._t) << '\'';
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, typename Enable = void>
|
||||
struct wrap_operand
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct wrap_operand<bool, void>
|
||||
{
|
||||
using type = boolean_operand;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct wrap_operand<T, typename std::enable_if<std::is_integral<T>::value>::type>
|
||||
{
|
||||
using type = integral_operand<T>;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct wrap_operand<T, typename std::enable_if<std::is_floating_point<T>::value>::type>
|
||||
{
|
||||
using type = floating_point_operand<T>;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct wrap_operand<T, typename std::enable_if<std::is_convertible<T, std::string>::value>::type>
|
||||
{
|
||||
using type = text_operand;
|
||||
};
|
||||
template<typename T>
|
||||
struct wrap_operand<T, typename std::enable_if<std::is_convertible<T, std::string>::value>::type>
|
||||
{
|
||||
using type = text_operand;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -48,192 +48,192 @@ namespace sqlpp
|
||||
Rhs _rhs;
|
||||
};
|
||||
|
||||
template<typename Db, typename Lhs, typename Rhs>
|
||||
struct interpreter_t<Db, assignment_t<Lhs, Rhs>>
|
||||
template<typename Context, typename Lhs, typename Rhs>
|
||||
struct interpreter_t<Context, assignment_t<Lhs, Rhs>>
|
||||
{
|
||||
using T = assignment_t<Lhs, Rhs>;
|
||||
template<typename Context>
|
||||
static Context& _(const T& t, Context& context)
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
interpret(t._lhs, context);
|
||||
if (trivial_value_is_null_t<Lhs>::value and t._rhs._is_trivial())
|
||||
{
|
||||
interpret(t._lhs, context);
|
||||
if (trivial_value_is_null_t<Lhs>::value and t._rhs._is_trivial())
|
||||
{
|
||||
context << "=NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
context << "=";
|
||||
interpret(t._rhs, context);
|
||||
}
|
||||
return context;
|
||||
context << "=NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
context << "=";
|
||||
interpret(t._rhs, context);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct equal_t: public detail::boolean::template operators<equal_t<Lhs, Rhs>>
|
||||
{
|
||||
using _value_type = detail::boolean;
|
||||
{
|
||||
using _value_type = detail::boolean;
|
||||
|
||||
template<typename L, typename R>
|
||||
template<typename L, typename R>
|
||||
equal_t(L&& l, R&& r):
|
||||
_lhs(std::forward<L>(l)),
|
||||
_rhs(std::forward<R>(r))
|
||||
{}
|
||||
{}
|
||||
|
||||
equal_t(const equal_t&) = default;
|
||||
equal_t(equal_t&&) = default;
|
||||
equal_t& operator=(const equal_t&) = default;
|
||||
equal_t& operator=(equal_t&&) = default;
|
||||
~equal_t() = default;
|
||||
equal_t(const equal_t&) = default;
|
||||
equal_t(equal_t&&) = default;
|
||||
equal_t& operator=(const equal_t&) = default;
|
||||
equal_t& operator=(equal_t&&) = default;
|
||||
~equal_t() = default;
|
||||
|
||||
private:
|
||||
Lhs _lhs;
|
||||
Rhs _rhs;
|
||||
};
|
||||
private:
|
||||
Lhs _lhs;
|
||||
Rhs _rhs;
|
||||
};
|
||||
|
||||
template<typename Db, typename Lhs, typename Rhs>
|
||||
struct interpreter_t<Db, equal_t<Lhs, Rhs>>
|
||||
template<typename Context, typename Lhs, typename Rhs>
|
||||
struct interpreter_t<Context, equal_t<Lhs, Rhs>>
|
||||
{
|
||||
using T = equal_t<Lhs, Rhs>;
|
||||
template<typename Context>
|
||||
static Context& interpret(const T& t, Context& context)
|
||||
|
||||
static Context& interpret(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
interpret(t._lhs, context);
|
||||
if (trivial_value_is_null_t<Lhs>::value and t._rhs._is_trivial())
|
||||
{
|
||||
context << "(";
|
||||
interpret(t._lhs, context);
|
||||
if (trivial_value_is_null_t<Lhs>::value and t._rhs._is_trivial())
|
||||
{
|
||||
context << "IS NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
context << "=";
|
||||
interpret(t._rhs, context);
|
||||
}
|
||||
context << ")";
|
||||
return context;
|
||||
context << "IS NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
context << "=";
|
||||
interpret(t._rhs, context);
|
||||
}
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct not_equal_t: public detail::boolean::template operators<not_equal_t<Lhs, Rhs>>
|
||||
{
|
||||
using _value_type = detail::boolean;
|
||||
{
|
||||
using _value_type = detail::boolean;
|
||||
|
||||
template<typename L, typename R>
|
||||
template<typename L, typename R>
|
||||
not_equal_t(L&& l, R&& r):
|
||||
_lhs(std::forward<L>(l)),
|
||||
_rhs(std::forward<R>(r))
|
||||
{}
|
||||
{}
|
||||
|
||||
not_equal_t(const not_equal_t&) = default;
|
||||
not_equal_t(not_equal_t&&) = default;
|
||||
not_equal_t& operator=(const not_equal_t&) = default;
|
||||
not_equal_t& operator=(not_equal_t&&) = default;
|
||||
~not_equal_t() = default;
|
||||
not_equal_t(const not_equal_t&) = default;
|
||||
not_equal_t(not_equal_t&&) = default;
|
||||
not_equal_t& operator=(const not_equal_t&) = default;
|
||||
not_equal_t& operator=(not_equal_t&&) = default;
|
||||
~not_equal_t() = default;
|
||||
|
||||
Lhs _lhs;
|
||||
Rhs _rhs;
|
||||
};
|
||||
Lhs _lhs;
|
||||
Rhs _rhs;
|
||||
};
|
||||
|
||||
template<typename Db, typename Lhs, typename Rhs>
|
||||
struct interpreter_t<Db, not_equal_t<Lhs, Rhs>>
|
||||
template<typename Context, typename Lhs, typename Rhs>
|
||||
struct interpreter_t<Context, not_equal_t<Lhs, Rhs>>
|
||||
{
|
||||
using T = not_equal_t<Lhs, Rhs>;
|
||||
template<typename Context>
|
||||
static Context& interpret(const T& t, Context& context)
|
||||
|
||||
static Context& interpret(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
interpret(t._lhs, context);
|
||||
if (trivial_value_is_null_t<Lhs>::value and t._rhs._is_trivial())
|
||||
{
|
||||
context << "(";
|
||||
interpret(t._lhs, context);
|
||||
if (trivial_value_is_null_t<Lhs>::value and t._rhs._is_trivial())
|
||||
{
|
||||
context << "IS NOT NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
context << "!=";
|
||||
interpret(t._rhs, context);
|
||||
}
|
||||
context << ")";
|
||||
return context;
|
||||
context << "IS NOT NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
context << "!=";
|
||||
interpret(t._rhs, context);
|
||||
}
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Lhs>
|
||||
struct not_t: public detail::boolean::template operators<not_t<Lhs>>
|
||||
{
|
||||
using _value_type = detail::boolean;
|
||||
{
|
||||
using _value_type = detail::boolean;
|
||||
|
||||
not_t(Lhs l):
|
||||
_lhs(l)
|
||||
{}
|
||||
not_t(Lhs l):
|
||||
_lhs(l)
|
||||
{}
|
||||
|
||||
not_t(const not_t&) = default;
|
||||
not_t(not_t&&) = default;
|
||||
not_t& operator=(const not_t&) = default;
|
||||
not_t& operator=(not_t&&) = default;
|
||||
~not_t() = default;
|
||||
not_t(const not_t&) = default;
|
||||
not_t(not_t&&) = default;
|
||||
not_t& operator=(const not_t&) = default;
|
||||
not_t& operator=(not_t&&) = default;
|
||||
~not_t() = default;
|
||||
|
||||
Lhs _lhs;
|
||||
};
|
||||
Lhs _lhs;
|
||||
};
|
||||
|
||||
template<typename Db, typename Lhs>
|
||||
struct interpreter_t<Db, not_t<Lhs>>
|
||||
template<typename Context, typename Lhs>
|
||||
struct interpreter_t<Context, not_t<Lhs>>
|
||||
{
|
||||
using T = not_t<Lhs>;
|
||||
template<typename Context>
|
||||
static Context& interpret(const T& t, Context& context)
|
||||
|
||||
static Context& interpret(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
if (trivial_value_is_null_t<Lhs>::value and t._lhs._is_trivial())
|
||||
{
|
||||
context << "(";
|
||||
if (trivial_value_is_null_t<Lhs>::value and t._lhs._is_trivial())
|
||||
{
|
||||
interpret(t._lhs, context);
|
||||
context << "IS NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
context << "NOT ";
|
||||
interpret(t._lhs, context);
|
||||
}
|
||||
context << ")";
|
||||
return context;
|
||||
interpret(t._lhs, context);
|
||||
context << "IS NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
context << "NOT ";
|
||||
interpret(t._lhs, context);
|
||||
}
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Lhs, typename O, typename Rhs>
|
||||
struct binary_expression_t: public O::_value_type::template operators<binary_expression_t<Lhs, O, Rhs>>
|
||||
{
|
||||
using _value_type = typename O::_value_type;
|
||||
{
|
||||
using _value_type = typename O::_value_type;
|
||||
|
||||
binary_expression_t(Lhs lhs, Rhs rhs):
|
||||
_lhs(lhs),
|
||||
_rhs(rhs)
|
||||
{}
|
||||
binary_expression_t(Lhs lhs, Rhs rhs):
|
||||
_lhs(lhs),
|
||||
_rhs(rhs)
|
||||
{}
|
||||
|
||||
binary_expression_t(const binary_expression_t&) = default;
|
||||
binary_expression_t(binary_expression_t&&) = default;
|
||||
binary_expression_t& operator=(const binary_expression_t&) = default;
|
||||
binary_expression_t& operator=(binary_expression_t&&) = default;
|
||||
~binary_expression_t() = default;
|
||||
binary_expression_t(const binary_expression_t&) = default;
|
||||
binary_expression_t(binary_expression_t&&) = default;
|
||||
binary_expression_t& operator=(const binary_expression_t&) = default;
|
||||
binary_expression_t& operator=(binary_expression_t&&) = default;
|
||||
~binary_expression_t() = default;
|
||||
|
||||
Lhs _lhs;
|
||||
Rhs _rhs;
|
||||
};
|
||||
Lhs _lhs;
|
||||
Rhs _rhs;
|
||||
};
|
||||
|
||||
template<typename Db, typename Lhs, typename O, typename Rhs>
|
||||
struct interpreter_t<Db, binary_expression_t<Lhs, O, Rhs>>
|
||||
template<typename Context, typename Lhs, typename O, typename Rhs>
|
||||
struct interpreter_t<Context, binary_expression_t<Lhs, O, Rhs>>
|
||||
{
|
||||
using T = binary_expression_t<Lhs, O, Rhs>;
|
||||
template<typename Context>
|
||||
static Context& interpret(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
interpret(t._lhs, context);
|
||||
context << T::O::_name;
|
||||
interpret(t._rhs, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
|
||||
static Context& interpret(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
interpret(t._lhs, context);
|
||||
context << T::O::_name;
|
||||
interpret(t._rhs, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -33,10 +33,10 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Db, typename Tuple>
|
||||
template<typename Context, typename Tuple>
|
||||
struct tuple_interpreter_t
|
||||
{
|
||||
template<typename Separator, typename Context>
|
||||
template<typename Separator>
|
||||
static void _(const Tuple& t, const Separator& separator, Context& context)
|
||||
{
|
||||
_impl(t, separator, context, type<0>());
|
||||
@@ -45,7 +45,7 @@ namespace sqlpp
|
||||
private:
|
||||
template<size_t> struct type {};
|
||||
|
||||
template<typename Separator, typename Context, size_t index>
|
||||
template<typename Separator, size_t index>
|
||||
static void _impl(const Tuple& t, const Separator& separator, Context& context, const type<index>&)
|
||||
{
|
||||
if (index)
|
||||
@@ -60,7 +60,7 @@ namespace sqlpp
|
||||
_impl(t, separator, context, type<index + 1>());
|
||||
}
|
||||
|
||||
template<typename Separator, typename Context>
|
||||
template<typename Separator>
|
||||
static void _impl(const Tuple& t, const Separator& separator, Context& context, const type<std::tuple_size<Tuple>::value>&)
|
||||
{
|
||||
}
|
||||
@@ -68,9 +68,9 @@ namespace sqlpp
|
||||
|
||||
template<typename Tuple, typename Separator, typename Context>
|
||||
auto interpret_tuple(const Tuple& t, const Separator& separator, Context& context)
|
||||
-> decltype(tuple_interpreter_t<typename std::decay<Context>::type::_database_t, typename std::decay<Tuple>::type>::_(t, separator, context))
|
||||
-> decltype(tuple_interpreter_t<typename std::decay<Context>::type, typename std::decay<Tuple>::type>::_(t, separator, context))
|
||||
{
|
||||
return tuple_interpreter_t<typename std::decay<Context>::type::_database_t, typename std::decay<Tuple>::type>::_(t, separator, context);
|
||||
return tuple_interpreter_t<typename std::decay<Context>::type, typename std::decay<Tuple>::type>::_(t, separator, context);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,21 +32,20 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Db, typename T>
|
||||
template<typename Context, typename T>
|
||||
struct interpreter_t
|
||||
{
|
||||
template<typename Context>
|
||||
static void _(const T& t, Context& context)
|
||||
{
|
||||
static_assert(detail::wrong<Db, T>::value, "missing interpreter specialization");
|
||||
}
|
||||
static void _(const T& t, Context& context)
|
||||
{
|
||||
static_assert(detail::wrong<Context, T>::value, "missing interpreter specialization");
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, typename Context>
|
||||
auto interpret(const T& t, Context& context)
|
||||
-> decltype(interpreter_t<typename std::decay<Context>::type::_database_t, typename std::decay<T>::type>::_(t, context))
|
||||
-> decltype(interpreter_t<typename std::decay<Context>::type, typename std::decay<T>::type>::_(t, context))
|
||||
{
|
||||
return interpreter_t<typename std::decay<Context>::type::_database_t, typename std::decay<T>::type>::_(t, context);
|
||||
return interpreter_t<typename std::decay<Context>::type, typename std::decay<T>::type>::_(t, context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user