Skip to content

Commit

Permalink
dirty
Browse files Browse the repository at this point in the history
  • Loading branch information
StarQTius committed Sep 30, 2024
1 parent 2f4ca46 commit 3c7414f
Show file tree
Hide file tree
Showing 6 changed files with 228 additions and 212 deletions.
26 changes: 13 additions & 13 deletions example/dynamixel-protocol-2.0.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ int main() {
std::cout << std::hex;

auto ping_ex1 = description.instantiate(ser,
upd::kw<"id"> = 1, upd::kw<"length"> = 3, upd::kw<"instruction"> = 1);
"id"_kw = 1, "length"_kw = 3, "instruction"_kw = 1);
if (!ping_ex1) {
return (int)ping_ex1.error();
}
Expand All @@ -174,12 +174,12 @@ int main() {
}

std::printf("Answer 1: \n");
std::printf("- id: %" PRIx8 "\n", (std::uint8_t)(*answer1)[upd::kw<"id">]);
std::printf("- length: %" PRIx16 "\n", (std::uint16_t)(*answer1)[upd::kw<"length">]);
std::printf("- instruction: %" PRIx8 "\n", (std::uint8_t)(*answer1)[upd::kw<"instruction">]);
std::printf("- error: %" PRIx8 "\n", (std::uint8_t)(*answer1)[upd::kw<"error">]);
std::printf("- model number: %" PRIx16 "\n", (std::uint16_t)(*answer1)[upd::kw<"model_number">]);
std::printf("- firmware version: %" PRIx8 "\n", (std::uint8_t)(*answer1)[upd::kw<"firmware_version">]);
std::printf("- id: %" PRIx8 "\n", (std::uint8_t)(*answer1)["id"_kw]);
std::printf("- length: %" PRIx16 "\n", (std::uint16_t)(*answer1)["length"_kw]);
std::printf("- instruction: %" PRIx8 "\n", (std::uint8_t)(*answer1)["instruction"_kw]);
std::printf("- error: %" PRIx8 "\n", (std::uint8_t)(*answer1)["error"_kw]);
std::printf("- model number: %" PRIx16 "\n", (std::uint16_t)(*answer1)["model_number"_kw]);
std::printf("- firmware version: %" PRIx8 "\n", (std::uint8_t)(*answer1)["firmware_version"_kw]);
std::printf("\n\n");

auto answer2_seq = bytearray{0xff, 0xff, 0xfd, 0x00, 0x02, 0x07, 0x00, 0x55, 0x00, 0x06, 0x04, 0x26, 0x6f, 0x6d};
Expand All @@ -189,11 +189,11 @@ int main() {
}

std::printf("Answer 2: \n");
std::printf("- id: %" PRIx8 "\n", (std::uint8_t)(*answer2)[upd::kw<"id">]);
std::printf("- length: %" PRIx16 "\n", (std::uint16_t)(*answer2)[upd::kw<"length">]);
std::printf("- instruction: %" PRIx8 "\n", (std::uint8_t)(*answer2)[upd::kw<"instruction">]);
std::printf("- error: %" PRIx8 "\n", (std::uint8_t)(*answer2)[upd::kw<"error">]);
std::printf("- model number: %" PRIx16 "\n", (std::uint16_t)(*answer2)[upd::kw<"model_number">]);
std::printf("- firmware version: %" PRIx8 "\n", (std::uint8_t)(*answer2)[upd::kw<"firmware_version">]);
std::printf("- id: %" PRIx8 "\n", (std::uint8_t)(*answer2)["id"_kw]);
std::printf("- length: %" PRIx16 "\n", (std::uint16_t)(*answer2)["length"_kw]);
std::printf("- instruction: %" PRIx8 "\n", (std::uint8_t)(*answer2)["instruction"_kw]);
std::printf("- error: %" PRIx8 "\n", (std::uint8_t)(*answer2)["error"_kw]);
std::printf("- model number: %" PRIx16 "\n", (std::uint16_t)(*answer2)["model_number"_kw]);
std::printf("- firmware version: %" PRIx8 "\n", (std::uint8_t)(*answer2)["firmware_version"_kw]);
std::printf("\n\n");
}
18 changes: 9 additions & 9 deletions include/upd/description.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -321,13 +321,13 @@ class description {
if constexpr (field.tag == field_tag::pure_field) {
constexpr auto width = field.width;
using representation = std::conditional_t<field.is_signed, xint<width>, xuint<width>>;
auto value = named_args[kw<field.identifier>];
return kw<field.identifier> = representation{value};
auto value = named_args[keyword<field.identifier>{}];
return keyword<field.identifier>{} = representation{value};
} else if constexpr (field.tag == field_tag::constant) {
return kw<field.identifier> = field.value;
return keyword<field.identifier>{} = field.value;
} else if constexpr (field.tag == field_tag::checksum) {
constexpr auto width = field.width;
return kw<field.identifier> = xuint<width>{field.init};
return keyword<field.identifier>{} = xuint<width>{field.init};
} else {
static_assert(UPD_ALWAYS_FALSE, "`field` is not a field object");
}
Expand All @@ -339,13 +339,13 @@ class description {
if constexpr (field.tag == field_tag::checksum) {
constexpr auto identifier = field.identifier;
auto &[op, init, get_range] = field;
auto &acc = retval[kw<identifier>];
auto &acc = retval[keyword<identifier>{}];
auto folder = invoker_iterator{
[&, op=op](auto x) { acc = op(acc, x); }
};

get_range(identifiers).for_each([&](auto id) {
return retval[kw<id.value>].serialize(ser, folder);
return retval[keyword<id.value>{}].serialize(ser, folder);
});
}
};
Expand All @@ -367,7 +367,7 @@ class description {
auto first_pass = [&](const auto &field) {
if constexpr (field.tag == field_tag::checksum) {
const auto &[op, init, get_range] = field;
auto &acc = accumulators[kw<field.identifier>];
auto &acc = accumulators[keyword<field.identifier>{}];
auto range = get_range(identifiers);
auto accumulate = [&, &op = op](auto identifier, const auto &value) {
constexpr auto p = [=](auto id_type) { return auto_constant<id_type->value == identifier>{}; };
Expand All @@ -393,7 +393,7 @@ class description {
return value;
}
};
return kw<identifier> = deserialize_into_xinteger<representation>(decorated_src, ser);
return keyword<identifier>{} = deserialize_into_xinteger<representation>(decorated_src, ser);
} else if constexpr (field.tag == field_tag::constant) {
constexpr auto width = field.width;
using representation = std::conditional_t<field.is_signed, xint<width>, xuint<width>>;
Expand All @@ -413,7 +413,7 @@ class description {
constexpr auto width = field.width;
using representation = std::conditional_t<field.is_signed, xint<width>, xuint<width>>;
auto received = deserialize_into_xinteger<representation>(detail::iterator_reference{src}, ser);
if (!err && accumulators[kw<identifier>] != received) {
if (!err && accumulators[keyword<identifier>{}] != received) {
err = error::checksum_mismatch;
}
} else {
Expand Down
12 changes: 12 additions & 0 deletions include/upd/detail/sequence.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#pragma once

#include <type_traits>

namespace upd::detail {

template<typename F, std::size_t... Is>
[[nodiscard]] constexpr auto apply_on_index_sequence(F &&f, std::index_sequence<Is...>) -> decltype(auto) {
return std::invoke(UPD_FWD(f), std::integral_constant<std::size_t, Is>{}...);
}

} // namespace upd::detail
129 changes: 1 addition & 128 deletions include/upd/named_tuple.hpp
Original file line number Diff line number Diff line change
@@ -1,130 +1,3 @@
#pragma once

#include <array>
#include <ranges>
#include <string>
#include <limits>
#include <tuple>
#include <type_traits>
#include <utility>

#include "description.hpp"
#include "detail/always_false.hpp"
#include "detail/integral_constant.hpp"
#include "detail/tuple_operations.hpp"
#include "detail/variadic/concat.hpp"
#include "detail/variadic/count.hpp"
#include "detail/variadic/find.hpp"
#include "integer.hpp"
#include "upd.hpp"

namespace upd {

template<std::size_t N>
struct name {
constexpr name(const char (&s)[N]): value{} {
std::ranges::copy(s, value);
}

template<std::size_t M>
[[nodiscard]] constexpr auto operator==(const name<M> &rhs) const noexcept -> bool {
return std::string_view{value} == std::string_view{rhs.value};
};

char value[N];
};

template<name>
struct kw_t;

template<name..., typename... Ts>
[[nodiscard]] constexpr auto name_tuple(std::tuple<Ts...>) noexcept;

template<typename... Named_Tuple_Ts>
[[nodiscard]] constexpr auto concat_named_tuple(Named_Tuple_Ts &&...);

template<typename Tuple_T, name... Ids>
class named_tuple {
using id_ts = detail::integral_constant_tuple_t<Ids...>;

template<name..., typename... Ts>
friend constexpr auto name_tuple(std::tuple<Ts...>) noexcept;

template<typename... Named_Tuple_Ts>
friend constexpr auto concat_named_tuple(Named_Tuple_Ts &&...);

public:
template<name Id>
[[nodiscard]] constexpr auto get() noexcept -> auto & {
using id_t = detail::integral_constant_t<Id>;
constexpr auto id_pos = detail::variadic::find_v<id_ts, id_t>;

static_assert(id_pos != detail::variadic::not_found, "`Id` does not belong to `Ids`");

return std::get<id_pos>(m_content);
}

template<name Id>
[[nodiscard]] constexpr auto get() const noexcept -> const auto & {
using id_t = detail::integral_constant_t<Id>;
constexpr auto id_pos = detail::variadic::find_v<id_ts, id_t>;

static_assert(id_pos != detail::variadic::not_found, "`Id` does not belong to `Ids`");

return std::get<id_pos>(m_content);
}

template<name Identifier>
[[nodiscard]] constexpr auto operator[](kw_t<Identifier>) noexcept(release) -> auto & {
return get<Identifier>();
}

template<name Identifier>
[[nodiscard]] constexpr auto operator[](kw_t<Identifier>) const noexcept(release) -> const auto & {
return get<Identifier>();
}

template<typename Serializer, typename OutputIt>
constexpr void serialize(Serializer &ser, OutputIt output) {
auto serialize_pack = [&](const auto &...xs) { (xs.serialize(ser, output), ...); };

std::apply(serialize_pack, m_content);
}

private:
constexpr explicit named_tuple(Tuple_T content, detail::integral_constant_tuple_t<Ids...>)
: m_content{UPD_FWD(content)} {}

Tuple_T m_content;
};

template<typename>
struct is_named_tuple_instance : std::false_type {};

template<typename Tuple, name... Identifiers>
struct is_named_tuple_instance<named_tuple<Tuple, Identifiers...>> : std::true_type {};

template<name... Ids, typename... Ts>
[[nodiscard]] constexpr auto name_tuple(std::tuple<Ts...> tuple) noexcept {
using id_ts = detail::integral_constant_tuple_t<Ids...>;

if constexpr (sizeof...(Ids) != sizeof...(Ts)) {
static_assert(UPD_ALWAYS_FALSE, "`Ids` and `Ts` must contain the same number of elements");
} else if constexpr (((detail::variadic::count_v<id_ts, detail::integral_constant_t<Ids>> != 1) || ...)) {
static_assert(UPD_ALWAYS_FALSE, "Each element in `Ids` must be unique");
} else {
return named_tuple{std::move(tuple), id_ts{}};
}
}

template<typename... Named_Tuple_Ts>
[[nodiscard]] constexpr auto concat_named_tuple(Named_Tuple_Ts &&...named_tuples) {
using id_ts = detail::variadic::concat_t<typename Named_Tuple_Ts::id_ts...>;

auto content = std::tuple_cat(UPD_FWD(named_tuples).m_content...);
auto name_content = [&](auto... id_iconsts) { return name_tuple<id_iconsts.value...>(std::move(content)); };

return std::apply(name_content, id_ts{});
}

} // namespace upd
#include "named_value.hpp"
Loading

0 comments on commit 3c7414f

Please sign in to comment.