3636#include " Descriptor.h"
3737#include " SmartPtrs.h"
3838#include " Exception.h"
39+ #include " StructBinding.h"
3940#include < charconv>
4041#include < cerrno>
4142#include < cstdlib>
@@ -2042,6 +2043,51 @@ namespace fbcpp
20422043 template <typename T>
20432044 T get (unsigned index);
20442045
2046+ // /
2047+ // / @brief Retrieves all output columns into a user-defined aggregate struct.
2048+ // / @tparam T An aggregate type whose fields match the output column count and types.
2049+ // / @return The populated struct with values from the current row.
2050+ // / @throws FbCppException if field count mismatches output column count.
2051+ // / @throws FbCppException if a NULL value is encountered for a non-optional field.
2052+ // /
2053+ template <Aggregate T>
2054+ T get ()
2055+ {
2056+ using namespace impl ::reflection;
2057+
2058+ constexpr std::size_t N = fieldCountV<T>;
2059+
2060+ if (N != outDescriptors.size ())
2061+ {
2062+ throw FbCppException (" Struct field count (" + std::to_string (N) +
2063+ " ) does not match output column count (" + std::to_string (outDescriptors.size ()) + " )" );
2064+ }
2065+
2066+ return getStruct<T>(std::make_index_sequence<N>{});
2067+ }
2068+
2069+ // /
2070+ // / @brief Sets all input parameters from fields of a user-defined aggregate struct.
2071+ // / @tparam T An aggregate type whose fields match the input parameter count.
2072+ // / @param value The struct containing parameter values.
2073+ // / @throws FbCppException if field count mismatches input parameter count.
2074+ // /
2075+ template <Aggregate T>
2076+ void set (const T& value)
2077+ {
2078+ using namespace impl ::reflection;
2079+
2080+ constexpr std::size_t N = fieldCountV<T>;
2081+
2082+ if (N != inDescriptors.size ())
2083+ {
2084+ throw FbCppException (" Struct field count (" + std::to_string (N) +
2085+ " ) does not match input parameter count (" + std::to_string (inDescriptors.size ()) + " )" );
2086+ }
2087+
2088+ setStruct (value, std::make_index_sequence<N>{});
2089+ }
2090+
20452091 private:
20462092 // /
20472093 // / @brief Validates and returns the descriptor for the given input parameter index.
@@ -2065,6 +2111,53 @@ namespace fbcpp
20652111 return outDescriptors[index];
20662112 }
20672113
2114+ // /
2115+ // / @brief Helper to retrieve all output columns into a struct.
2116+ // /
2117+ template <typename T, std::size_t ... Is>
2118+ T getStruct (std::index_sequence<Is...>)
2119+ {
2120+ using namespace impl ::reflection;
2121+
2122+ return T{getStructField<FieldType<T, Is>>(static_cast <unsigned >(Is))...};
2123+ }
2124+
2125+ // /
2126+ // / @brief Helper to get a single field value, throwing if NULL for non-optional fields.
2127+ // /
2128+ template <typename F>
2129+ auto getStructField (unsigned index)
2130+ {
2131+ using namespace impl ::reflection;
2132+
2133+ if constexpr (isOptionalV<F>)
2134+ return get<F>(index);
2135+ else
2136+ {
2137+ auto opt = get<std::optional<F>>(index);
2138+
2139+ if (!opt.has_value ())
2140+ {
2141+ throw FbCppException (
2142+ " Null value encountered for non-optional field at index " + std::to_string (index));
2143+ }
2144+
2145+ return std::move (opt.value ());
2146+ }
2147+ }
2148+
2149+ // /
2150+ // / @brief Helper to set all input parameters from a struct.
2151+ // /
2152+ template <typename T, std::size_t ... Is>
2153+ void setStruct (const T& value, std::index_sequence<Is...>)
2154+ {
2155+ using namespace impl ::reflection;
2156+
2157+ const auto tuple = toTupleRef (value);
2158+ (set (static_cast <unsigned >(Is), std::get<Is>(tuple)), ...);
2159+ }
2160+
20682161 // /
20692162 // / @brief Converts and writes numeric parameter values following descriptor rules.
20702163 // /
0 commit comments