Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mpp: introduce object encoding/decoding #63

Merged
merged 5 commits into from
Nov 7, 2023
Merged

Conversation

alyapunov
Copy link
Contributor

Now it became possible to pass an object of any class to
mpp::encode and mpp::decode if a co/dec rule is supplied.

There are two ways to specify a rule for a particular class:

  • through static member of the class, that is mpp member for
    ecoding/decoding, mpp_enc for encoding only and mpp_dec fo
    decoding only.
  • via partial specialization of special global class, that is
    mpp_rule for ecoding/decoding, mpp_enc_rule for ecoding and
    mpp_dec_rule for decoding. In any of these cases a static
    member value is expected in the specialization.

In any case the value of the encoding rule must be a constexpr
expression that could contain any values, including standard
aggregates like std::tuple and pointers to members of the class
that must be encoded/decoded.

Note that one can specify one rule for encoding/decoding as well
as different rules for encoding and decoding.

Examples:

struct IntegerWrapper {
	int i;
	static constexpr auto mpp = &IntegerWrapper::i;
};

An object of such a class will be encoded/decoded as one integer
(MP_INT) value.

struct Triplet {
	int a;
	double b;
	std::string c;
};

template <>
struct mpp_rule<Triplet> {
	static constexpr auto value = std::make_tuple(&Triplet::a,
						      &Triplet::b,
						      &Triplet::c);
};

An object of this class will be encoded/decoded as array (MP_ARR)
of three values - a, b, c - with the corresponding types.

struct Error {
	int code = 0;
	std::string descr;

	static constexpr auto mpp = std::make_tuple(
		std::make_pair(0, &Error::code),
		std::make_pair(1, &Error::descr));
};

This error will be encoded/decoded as map (MP_MAP) with integer
keys (0, 1) and corresponding values (code, descr).

Make it to return rvalue references as well (like std::get does).
By default tuples of pairs are interpeted as MP_MAP type and are
encoded correspondingly. But by mistake is this case all keys were
encoded before all values.

Fix it by reordering keys and values so that key-value pairs are
encoded sequentially.

Add a test for that case.
It's a separated utility that is designed for locating of
encode/decode rule of a class. It detects presence of static
members - `mpp`, `mpp_enc`, `mpp_dec` as well as partial
specialization of special classes `mpp_rule`, `mpp_enc_rule`,
`mpp_dec_rule`.

This utility will be uses in further commits for object
encoding/decoding.
No logical changes, preparation for further commits.
Now it became possible to pass an object of any class to
mpp::encode and mpp::decode if a co/dec rule is supplied.

There are two ways to specify a rule for a particular class:
* through static member of the class, that is `mpp` member for
  ecoding/decoding, `mpp_enc` for encoding only and `mpp_dec` fo
  decoding only.
* via partial specialization of special global class, that is
  `mpp_rule` for ecoding/decoding, `mpp_enc_rule` for ecoding and
  `mpp_dec_rule` for decoding. In any of these cases a static
  member `value` is expected in the specialization.

In any case the value of the encoding rule must be a constexpr
expression that could contain any values, including standard
aggregates like std::tuple and pointers to members of the class
that must be encoded/decoded.

Note that one can specify one rule for encoding/decoding as well
as different rules for encoding and decoding.

Examples:

```
struct IntegerWrapper {
	int i;
	static constexpr auto mpp = &IntegerWrapper::i;
};
```
An object of such a class will be encoded/decoded as one integer
(MP_INT) value.

```
struct Triplet {
	int a;
	double b;
	std::string c;
};

template <>
struct mpp_rule<Triplet> {
	static constexpr auto value = std::make_tuple(&Triplet::a,
						      &Triplet::b,
						      &Triplet::c);
};
```
An object of this class will be encoded/decoded as array (MP_ARR)
of three values - a, b, c - with the corresponding types.

```
struct Error {
	int code = 0;
	std::string descr;

	static constexpr auto mpp = std::make_tuple(
		std::make_pair(0, &Error::code),
		std::make_pair(1, &Error::descr));
};
```
This error will be encoded/decoded as map (MP_MAP) with integer
keys (0, 1) and corresponding values (code, descr).
@alyapunov alyapunov merged commit 50c0b1b into master Nov 7, 2023
8 checks passed
@alyapunov alyapunov deleted the alyapunov/class-rules branch July 10, 2024 11:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant