Skip to content

Commit

Permalink
- cxon: uniform class read/write template parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
oknenavin committed Jun 14, 2024
1 parent 92fbf36 commit be46820
Show file tree
Hide file tree
Showing 2 changed files with 192 additions and 194 deletions.
166 changes: 83 additions & 83 deletions src/cxon/lang/cbor/class.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -13,33 +13,33 @@

namespace cxon { namespace cbor { namespace cls {

template <typename S>
template <typename T>
struct default_false {
constexpr bool operator ()(const S&) const noexcept { return false; }
constexpr bool operator ()(const T&) const noexcept { return false; }
};

template <typename F, typename D>
struct field {
using type = F;
char const*const name;
using type = F;
char const* name;
std::size_t nale;
type value;
D dflt;
type value;
D dflt;
};
template <typename S, std::size_t N, typename F = sink<>>
constexpr auto make_field(const char (&name)[N], F f) -> field<F, default_false<S>>;
template <typename S, std::size_t N, typename F, typename D>
template <typename T, std::size_t N, typename F = sink<>>
constexpr auto make_field(const char (&name)[N], F f) -> field<F, default_false<T>>;
template <typename T, std::size_t N, typename F, typename D>
constexpr auto make_field(const char (&name)[N], F f, D dflt) -> field<F, D>;

template <typename X, typename S, typename F, typename II, typename Cx>
inline bool read_field(S& s, const F& f, II& i, II e, Cx& cx);
template <typename X, typename O, typename S, typename F, typename Cx>
inline bool write_field(O& o, const S& s, const F& f, Cx& cx);
template <typename X, typename T, typename F, typename II, typename Cx>
inline bool read_field(T& t, const F& f, II& i, II e, Cx& cx);
template <typename X, typename O, typename T, typename F, typename Cx>
inline bool write_field(O& o, const T& t, const F& f, Cx& cx);

template <typename ...F>
using fields = std::tuple<F...>;
template <typename ...F>
constexpr fields<F...> make_fields(F&&... f);
template <typename ...Fs>
using fields = std::tuple<Fs...>;
template <typename ...Fs>
constexpr fields<Fs...> make_fields(Fs&&... fs);

}}}

Expand All @@ -49,109 +49,109 @@ namespace cxon { namespace cbor { namespace cls {

// field

template <typename S, std::size_t N, typename F>
constexpr auto make_field(const char (&name)[N], F f) -> field<F, default_false<S>> {
template <typename T, std::size_t N, typename F>
constexpr auto make_field(const char (&name)[N], F f) -> field<F, default_false<T>> {
return { name, N - 1, f, {} };
}
template <typename S, std::size_t N, typename F, typename D>
template <typename T, std::size_t N, typename F, typename D>
constexpr auto make_field(const char (&name)[N], F f, D dflt) -> field<F, D> {
return { name, N - 1, f, dflt };
}

namespace imp {

template <typename S, typename F>
constexpr auto field_value_(S& s, const F& f)
-> enable_if_t< std::is_member_pointer<typename F::type>::value, decltype(s.*f.value)&>
{ return s.*f.value; }
template <typename S, typename F>
constexpr auto field_value_(S&, const F& f)
template <typename T, typename F>
constexpr auto field_value_(T& t, const F& f)
-> enable_if_t< std::is_member_pointer<typename F::type>::value, decltype(t.*f.value)&>
{ return t.*f.value; }
template <typename T, typename F>
constexpr auto field_value_(T&, const F& f)
-> enable_if_t<!std::is_member_pointer<typename F::type>::value, decltype(*f.value)&>
{ return *f.value; }

}

namespace imp {

template <typename X, typename S, typename F, typename II, typename Cx>
inline auto read_field_(S& s, const F& f, II& i, II e, Cx& cx)
template <typename X, typename T, typename F, typename II, typename Cx>
inline auto read_field_(T& t, const F& f, II& i, II e, Cx& cx)
-> enable_if_t<!is_sink<typename F::type>::value, bool>
{
return read_value<X>(field_value_(s, f), i, e, cx);
return read_value<X>(field_value_(t, f), i, e, cx);
}
template <typename X, typename S, typename F, typename II, typename Cx>
inline auto read_field_(S&, const F& f, II& i, II e, Cx& cx)
template <typename X, typename T, typename F, typename II, typename Cx>
inline auto read_field_(T&, const F& f, II& i, II e, Cx& cx)
-> enable_if_t< is_sink<typename F::type>::value, bool>
{
return sink_read<X>(f.value, i, e, cx);
}

template <typename X, typename O, typename S, typename F, typename Cx>
inline auto write_field_(O& o, const S& s, const F& f, Cx& cx)
template <typename X, typename O, typename T, typename F, typename Cx>
inline auto write_field_(O& o, const T& t, const F& f, Cx& cx)
-> enable_if_t<!is_sink<typename F::type>::value, bool>
{
return write_value<X>(o, f.name, cx) && write_value<X>(o, field_value_(s, f), cx);
return write_value<X>(o, f.name, cx) && write_value<X>(o, field_value_(t, f), cx);
}
template <typename X, typename O, typename S, typename F, typename Cx>
constexpr auto write_field_(O&, const S&, const F&, Cx&) noexcept
template <typename X, typename O, typename T, typename F, typename Cx>
constexpr auto write_field_(O&, const T&, const F&, Cx&) noexcept
-> enable_if_t< is_sink<typename F::type>::value, bool>
{
return true;
}

}
template <typename X, typename S, typename F, typename II, typename Cx>
inline bool read_field(S& s, const F& f, II& i, II e, Cx& cx) {
return imp::read_field_<X>(s, f, i, e, cx);
template <typename X, typename T, typename F, typename II, typename Cx>
inline bool read_field(T& t, const F& f, II& i, II e, Cx& cx) {
return imp::read_field_<X>(t, f, i, e, cx);
}
template <typename X, typename O, typename S, typename F, typename Cx>
inline bool write_field(O& o, const S& s, const F& f, Cx& cx) {
return imp::write_field_<X>(o, s, f, cx);
template <typename X, typename O, typename T, typename F, typename Cx>
inline bool write_field(O& o, const T& t, const F& f, Cx& cx) {
return imp::write_field_<X>(o, t, f, cx);
}

// fields

template <typename ...F>
constexpr fields<F...> make_fields(F&&... f) {
return std::make_tuple(std::forward<F>(f)...);
template <typename ...Fs>
constexpr fields<Fs...> make_fields(Fs&&... fs) {
return { std::forward<Fs>(fs)... };
}

namespace imp {

template <typename X, std::size_t N, std::size_t L>
struct read_ {
template <typename S, typename F, typename II, typename Cx>
static bool field(S& s, const char* name, const F& fs, int (&st)[L], II& i, II e, Cx& cx) {
template <typename T, typename Fs, typename II, typename Cx>
static bool field(T& t, const char* name, const Fs& fs, int (&st)[L], II& i, II e, Cx& cx) {
return st[N] == 0 && std::char_traits<char>::compare(std::get<N>(fs).name, name, std::get<N>(fs).nale + 1) == 0 ?
(st[N] = 1,read_field<X>(s, std::get<N>(fs), i, e, cx)) :
read_<X, N + 1, L>::field(s, name, fs, st, i, e, cx)
(st[N] = 1, read_field<X>(t, std::get<N>(fs), i, e, cx)) :
read_<X, N + 1, L>::field(t, name, fs, st, i, e, cx)
;
}
};
template <typename X, std::size_t N>
struct read_<X, N, N> {
template <typename S, typename F, typename II, typename Cx>
static constexpr bool field(S&, const char*, const F&, int (&)[N], II&, II, Cx&) noexcept {
template <typename T, typename Fs, typename II, typename Cx>
static constexpr bool field(T&, const char*, const Fs&, int (&)[N], II&, II, Cx&) noexcept {
return false;
}
};

template <typename X, std::size_t N, typename S, typename F, typename II, typename Cx>
constexpr bool read_field_(S& s, const char* name, const F& fs, int (&st)[N], II& i, II e, Cx& cx) {
return read_<X, 0, N>::field(s, name, fs, st, i, e, cx);
template <typename X, std::size_t N, typename T, typename Fs, typename II, typename Cx>
constexpr bool read_field_(T& t, const char* name, const Fs& fs, int (&st)[N], II& i, II e, Cx& cx) {
return read_<X, 0, N>::field(t, name, fs, st, i, e, cx);
}

}
template <typename X, typename S, typename ...F, typename II, typename Cx>
inline bool read_fields(S& s, const fields<F...>& fs, II& i, II e, Cx& cx) {
template <typename X, typename T, typename ...Fs, typename II, typename Cx>
inline bool read_fields(T& t, const fields<Fs...>& fs, II& i, II e, Cx& cx) {
std::size_t n;
if (cbor::cnt::read_size_le<X>(n, sizeof...(F), i, e, cx)) {
int st[sizeof...(F)] = {0};
if (cbor::cnt::read_size_le<X>(n, sizeof...(Fs), i, e, cx)) {
int st[sizeof...(Fs)] = {0};
for (char id[bio::ids_len_max::constant<napa_type<Cx>>(64)]; n; --n) {
II const o = i;
if (!read_value<X>(id, i, e, cx))
return false;
if (!imp::read_field_<X>(s, id, fs, st, i, e, cx))
if (!imp::read_field_<X>(t, id, fs, st, i, e, cx))
return cx && (bio::rewind(i, o), cx/cbor::read_error::unexpected);
}
}
Expand All @@ -162,53 +162,53 @@ namespace cxon { namespace cbor { namespace cls {

template <std::size_t N, std::size_t L>
struct field_ {
template <typename S, typename F>
static unsigned state(const S& s, const F& fs, int (&st)[L]) {
using T = typename std::tuple_element<N, F>::type;
st[N] = !std::get<N>(fs).dflt(s) && !is_sink<typename T::type>::value;
return st[N] + field_<N + 1, L>::state(s, fs, st);
template <typename T, typename Fs>
static unsigned state(const T& t, const Fs& fs, int (&st)[L]) {
using E = typename std::tuple_element<N, Fs>::type;
st[N] = !std::get<N>(fs).dflt(t) && !is_sink<typename E::type>::value;
return st[N] + field_<N + 1, L>::state(t, fs, st);
}
};
template <std::size_t N>
struct field_<N, N> {
template <typename S, typename F>
static constexpr unsigned state(const S&, const F&, int (&)[N]) noexcept {
template <typename T, typename Fs>
static constexpr unsigned state(const T&, const Fs&, int (&)[N]) noexcept {
return 0;
}
};
template <std::size_t N, typename S, typename F>
constexpr unsigned field_state_(const S& s, const F& fs, int (&st)[N]) {
return field_<0, N>::state(s, fs, st);
template <std::size_t N, typename T, typename Fs>
constexpr unsigned field_state_(const T& t, const Fs& fs, int (&st)[N]) {
return field_<0, N>::state(t, fs, st);
}

template <typename X, std::size_t N, std::size_t L>
struct write_ {
template <typename S, typename F, typename O, typename Cx>
static bool field(O& o, const S& s, const F& fs, int (&st)[L], Cx& cx) {
return (std::get<N>(fs).dflt(s) || write_field<X>(o, s, std::get<N>(fs), cx)) &&
write_<X, N + 1, L>::field(o, s, fs, st, cx)
template <typename T, typename Fs, typename O, typename Cx>
static bool field(O& o, const T& t, const Fs& fs, int (&st)[L], Cx& cx) {
return (std::get<N>(fs).dflt(t) || write_field<X>(o, t, std::get<N>(fs), cx)) &&
write_<X, N + 1, L>::field(o, t, fs, st, cx)
;
}
};
template <typename X, std::size_t N>
struct write_<X, N, N> {
template <typename S, typename F, typename O, typename Cx>
static constexpr bool field(O&, const S&, const F&, int (&)[N], Cx&) noexcept {
template <typename T, typename Fs, typename O, typename Cx>
static constexpr bool field(O&, const T&, const Fs&, int (&)[N], Cx&) noexcept {
return true;
}
};
template <typename X, typename S, typename F, std::size_t N, typename O, typename Cx>
constexpr bool write_fields_(O& o, const S& s, const F& fs, int (&st)[N], Cx& cx) {
return write_<X, 0, N>::field(o, s, fs, st, cx);
template <typename X, typename T, typename Fs, std::size_t N, typename O, typename Cx>
constexpr bool write_fields_(O& o, const T& t, const Fs& fs, int (&st)[N], Cx& cx) {
return write_<X, 0, N>::field(o, t, fs, st, cx);
}

}
template <typename X, typename S, typename ...F, typename O, typename Cx>
inline bool write_fields(O& o, const S& s, const fields<F...>& fs, Cx& cx) {
int st[sizeof...(F)] = {0};
auto const ct = imp::field_state_<sizeof...(F)>(s, fs, st);
template <typename X, typename T, typename ...Fs, typename O, typename Cx>
inline bool write_fields(O& o, const T& t, const fields<Fs...>& fs, Cx& cx) {
int st[sizeof...(Fs)] = {0};
auto const ct = imp::field_state_<sizeof...(Fs)>(t, fs, st);
return cbor::cnt::write_size<X>(o, X::map, ct, cx) &&
imp::write_fields_<X>(o, s, fs, st, cx)
imp::write_fields_<X>(o, t, fs, st, cx)
;
}

Expand Down
Loading

0 comments on commit be46820

Please sign in to comment.