8#include <reflection-cpp/reflection.hpp> 
   19template <
size_t... Ints>
 
   26    struct IsSqlElements: std::false_type
 
   30    template <
size_t... Ints>
 
   31    struct IsSqlElements<
SqlElements<Ints...>>: std::true_type
 
   38concept NotSqlElements = !detail::IsSqlElements<T>::value;
 
   46template <
typename Record>
 
   49template <
typename... Records>
 
   55    template <std::
size_t I, 
typename Record>
 
   56    constexpr std::optional<size_t> FindPrimaryKeyIndex()
 
   59        if constexpr (I < Reflection::CountMembers<Record>)
 
   61            if constexpr (IsPrimaryKey<Reflection::MemberTypeOf<I, Record>>)
 
   64                return FindPrimaryKeyIndex<I + 1, Record>();
 
   72template <
typename Record>
 
   73constexpr size_t RecordPrimaryKeyIndex =
 
   74    detail::FindPrimaryKeyIndex<0, Record>().value_or((std::numeric_limits<size_t>::max)());
 
   77template <
typename Record>
 
   78decltype(
auto) RecordPrimaryKeyOf(Record&& record)
 
   82    return Reflection::GetMemberAt<RecordPrimaryKeyIndex<std::remove_cvref_t<Record>>>(std::forward<Record>(record));
 
   88    template <
typename Record>
 
   89    struct RecordPrimaryKeyTypeHelper
 
   94    template <
typename Record>
 
   95        requires(RecordPrimaryKeyIndex<Record> < Reflection::CountMembers<Record>)
 
   96    struct RecordPrimaryKeyTypeHelper<Record>
 
   98        using type = 
typename Reflection::MemberTypeOf<RecordPrimaryKeyIndex<Record>, Record>::ValueType;
 
  104template <
typename Record>
 
  105using RecordPrimaryKeyType = 
typename details::RecordPrimaryKeyTypeHelper<Record>::type;
 
  108template <
typename Record, 
typename TargetMappable>
 
  109void MapFromRecordFields(Record&& record, TargetMappable& target)
 
  111    Reflection::EnumerateMembers(std::forward<Record>(record), [&]<std::size_t I>(
auto const& field) {
 
  112        using MemberType = Reflection::MemberTypeOf<I, Record>;
 
  113        static_assert(IsField<MemberType>, 
"Record member must be a Field<> type");
 
  114        static_assert(std::is_assignable_v<
decltype(target[I]), 
decltype(field.Value())>,
 
  115                      "Target must support operator[] with the field type");
 
  116        target[I] = field.Value();
 
  126    { field.Value() } -> std::convertible_to<typename T::ValueType const&>;
 
  127    { mutableField.MutableValue() } -> std::convertible_to<typename T::ValueType&>;
 
  128    { field.IsModified() } -> std::convertible_to<bool>;
 
  129    { mutableField.SetModified(
bool {}) } -> std::convertible_to<void>;
 
 
  136template <
typename Record>
 
  138    Reflection::FoldMembers<Record>(
size_t { 0 }, []<
size_t I, 
typename Field>(
size_t const accum) 
constexpr {
 
  139        if constexpr (FieldWithStorage<Field>)
 
  145template <
typename Record>
 
  146concept RecordWithStorageFields = (RecordStorageFieldCount<Record> > 0);
 
  151    template <auto Test, 
typename T>
 
  152    constexpr bool CheckFieldProperty = Reflection::FoldMembers<T>(
false, []<
size_t I, 
typename Field>(
bool const accum) {
 
  153        if constexpr (Test.template operator()<Field>())
 
  165constexpr bool HasPrimaryKey = detail::CheckFieldProperty<[]<typename Field>() { 
return IsPrimaryKey<Field>; }, T>;
 
  172    detail::CheckFieldProperty<[]<typename Field>() { 
return IsAutoIncrementPrimaryKey<Field>; }, T>;
 
 
  177template <
typename Record>
 
  178inline LIGHTWEIGHT_FORCE_INLINE RecordPrimaryKeyType<Record> 
GetPrimaryKeyField(Record 
const& record) 
noexcept 
  181    static_assert(HasPrimaryKey<Record>, 
"Record must have a primary key");
 
  183    auto result = RecordPrimaryKeyType<Record> {};
 
  184    Reflection::EnumerateMembers(record, [&]<
size_t I, 
typename FieldType>(FieldType 
const& field) {
 
  185        if constexpr (IsPrimaryKey<FieldType> && std::same_as<FieldType, RecordPrimaryKeyType<Record>>)
 
 
Represents a record type that can be used with the DataMapper.
LIGHTWEIGHT_FORCE_INLINE RecordPrimaryKeyType< Record > GetPrimaryKeyField(Record const &record) noexcept
constexpr bool HasAutoIncrementPrimaryKey
Tests if the given record type does contain an auto increment primary key.
std::integer_sequence< size_t, Ints... > SqlElements
Represents a sequence of indexes that can be used alongside Query() to retrieve only part of the reco...
constexpr size_t RecordStorageFieldCount
constexpr bool HasPrimaryKey
Tests if the given record type does contain a primary key.