Transparent std::optional - #1250
Conversation
|
I haven't read any guidelines about commit message(if there is any). If something is wrong i'm willing to fix it ofcourse |
|
Sorry for not seeing this work earlier @fallenworld1. Don't worry too much about the commit messages; just "short line followed by blank line and explanation" should do. For now it looks like tests are currently failing because of this warning: But first I'd like to understand the patch a bit better. It does look as if So let's focus on that. The nice-to-have changes might be better in a separate PR, so we can review and merge those independently. Or I can make the changes directly on my end, just to get them out of the way. (Less work for you, but does rob you of some credits in git.) I'm not sure the change in Finally, a personal code style preference: in libpqxx I don't nest namespaces like.... namespace outer
{
// ...
namespace inner
{
// ...
}
}I feel that's too easy to get mixed up. Instead, I write them as separate namespaces: namespace outer
{
// ...
} // namespace outer
namespace outer::inner
{
// ...
} |
|
To make my earlier note a bit clearer: Fixing it properly could be a bit more complicated. |
|
I don't think we should handle all possible containers. std::uniquer_ptr, std::shared_ptr and std::optional should cover 99% of cases. Also user can always extend by making a simple wrapper for params. |
|
We should definitely address the real problem though, not patch it over for select types. |
|
I'm not sure generic approach exists. What it may look like: namespace pqxx::detail {
template<typename E> inline constexpr bool is_optional_v = false;
template<typename E> inline constexpr bool is_optional_v<::std::optional<E>> = true;
template<typename E> inline constexpr bool is_smart_ptr_v = false;
template<typename E> inline constexpr bool is_smart_ptr_v<::std::unique_ptr<E>> = true;
template<typename E> inline constexpr bool is_smart_ptr_v<::std::shared_ptr<E>> = true;
}
namespace pqxx {
template<class T>
struct nested_traits
{
static void extract([[maybe_unused]] T &&value) { }
};
template<class T>
concept optional = detail::is_optional_v<T>;
template<optional T>
struct nested_traits<T>
{
static auto &extract(const T& value) { return value.value(); }
};
template<class T>
concept smart_pointer = detail::is_smart_ptr_v<T>;
template<smart_pointer T>
struct nested_traits<T>
{
static auto &extract(const T& value) { return *value; }
};
} // namespace pqxx
template<typename T>
concept nested = !std::is_same_v<decltype(pqxx::nested_traits<T>::extract(std::declval<T>())), void>;
template<nested T>void append(T &&value, sl loc = sl::current()) &
{
if (is_null(value))
{
m_params.emplace_back();
}
else
{
append(pqxx::nested_traits<T>::extract(std::forward<T>(value)), loc);
}
}user can extend by specifying nested_traits |
|
Actually, I think there may be a simpler solution! In So we'd do... if constexpr (pqxx::always_null<TYPE>())
{
// ...
}
else if (is_null(value))
{
// ...
}
else if (param_format(value) == format::binary)
{
// THIS PART IS NEW
// "There are separate binary overloads, but nevertheless this can happen
// if a binary param doesn't look like a binary because it's wrapped inside
// a std::optional or a smart pointer."
}
else
{
// ...
}What would the new clause do? Two things, essentially:
|
|
I don't think we have any helpers yet for dereferencing a It does probably make sense to have a trait to identify types like |
|
I've ran into a problem with arguments lifetime. pqxx::params p;
p.append(std::something<binary>{value});
// or something more real
class Message {
std::optional<std::vector<std::byte>> get_payload()...
};
tx.exec(params{message.get_payload()});is going to append bytes_view creating a very easy path to store a dangling value there, not sure how to notify user about this. |
1. recognize std::optional in params::append and append its value(improves std::optional<binary> handling) 2. move value in append(params&&) 3. implement TODO for empty m_values
f58d385 to
c8d97a3
Compare
|
There is one standard concept that may help: I'm also exploring a solution for the main problem by the way. It involves introducing a new traits type for such things as One of the great things about this is that it may make And, crucially, |
Uh oh!
There was an error while loading. Please reload this page.