Skip to content
Snippets Groups Projects
Commit 7017637a authored by Andrey Saranchin's avatar Andrey Saranchin Committed by Vladimir Davydov
Browse files

core: populate mp_ctx with virtual copy

We are going to populate port_c with mp_object, which requires mp_ctx.
However, we want to have an ability to dump one port_c instance several
times, so we need to add virtual copy to mp_ctx.

It would be fair to say that copy constructor must accept `src` as a
constant object, but this approach is inconvinient in C, and such method
would be embarrassing to use in our code. So `src` is not constant in
copy constructor.

Method copy of mp_box_ctx is not implemented because it's not trivial,
it probably will require reference counting in tuple_format_map. Anyway,
it is not needed now, so that's not a problem.

Also, mp_ctx_move required dst to be default initialized. However, since
it provides semantics of move constructor, we shouldn't expect dst to be
initialized at all, since constructor is used to construct an
uninitialized object. So let's drop this requirement along the way.

NO_TEST=trivial
NO_CHANGELOG=internal
NO_DOC=internal
parent f9de16a3
No related branches found
No related tags found
No related merge requests found
......@@ -15,7 +15,21 @@ mp_box_ctx_destroy(struct mp_ctx *ctx)
void
mp_box_ctx_move(struct mp_ctx *dst, struct mp_ctx *src)
{
mp_ctx_move_default(dst, src);
tuple_format_map_move(&mp_box_ctx_check(dst)->tuple_format_map,
/* Destination is not necessarily an mp_box_ctx instance. */
struct mp_box_ctx *dst_box = (struct mp_box_ctx *)dst;
tuple_format_map_move(&dst_box->tuple_format_map,
&mp_box_ctx_check(src)->tuple_format_map);
/*
* Move base mp_ctx after format map to be able to check virtual
* methods of src.
*/
mp_ctx_move_default(dst, src);
}
void
mp_box_ctx_copy(struct mp_ctx *dst, struct mp_ctx *src)
{
(void)dst;
(void)src;
unreachable();
}
......@@ -26,6 +26,8 @@ struct mp_box_ctx {
void (*destroy)(struct mp_ctx *ctx);
/** See `mp_ctx::move`. */
void (*move)(struct mp_ctx *dst, struct mp_ctx *src);
/** See `mp_ctx::copy`. */
void (*copy)(struct mp_ctx *dst, struct mp_ctx *src);
/** Mapping of format identifiers to tuple formats. */
struct tuple_format_map tuple_format_map;
};
......@@ -45,6 +47,12 @@ mp_box_ctx_destroy(struct mp_ctx *ctx);
void
mp_box_ctx_move(struct mp_ctx *dst, struct mp_ctx *src);
/**
* 'Virtual' copy stub. Must not be called.
*/
void
mp_box_ctx_copy(struct mp_ctx *dst, struct mp_ctx *src);
static inline struct mp_box_ctx *
mp_box_ctx_check(struct mp_ctx *base)
{
......@@ -58,7 +66,7 @@ mp_box_ctx_create(struct mp_box_ctx *ctx, struct mh_strnu32_t *translation,
const char *tuple_formats)
{
mp_ctx_create((struct mp_ctx *)ctx, translation, mp_box_ctx_destroy,
mp_box_ctx_move);
mp_box_ctx_move, mp_box_ctx_copy);
if (tuple_formats == NULL) {
tuple_format_map_create_empty(&ctx->tuple_format_map);
return 0;
......
......@@ -9,10 +9,21 @@
void
mp_ctx_move_default(struct mp_ctx *dst, struct mp_ctx *src)
{
assert(dst->translation == NULL);
assert(dst->destroy == NULL);
assert(dst->move == mp_ctx_move_default);
SWAP(dst->translation, src->translation);
dst->translation = src->translation;
src->translation = NULL;
dst->destroy = src->destroy;
src->destroy = NULL;
dst->move = src->move;
src->move = NULL;
dst->copy = src->copy;
src->copy = NULL;
}
void
mp_ctx_copy_default(struct mp_ctx *dst, struct mp_ctx *src)
{
dst->translation = src->translation;
dst->destroy = src->destroy;
dst->move = src->move;
dst->copy = src->copy;
}
......@@ -36,6 +36,12 @@ struct mp_ctx {
* Cannot be `NULL`.
*/
void (*move)(struct mp_ctx *dst, struct mp_ctx *src);
/**
* 'Virtual' copy. Copies @a src to @a dst.
*
* Cannot be `NULL`.
*/
void (*copy)(struct mp_ctx *dst, struct mp_ctx *src);
/**
* Implementation dependent content. Needed to declare an abstract
* MsgPack context instance on stack.
......@@ -46,22 +52,30 @@ struct mp_ctx {
static inline void
mp_ctx_create(struct mp_ctx *ctx, struct mh_strnu32_t *translation,
void (*destroy)(struct mp_ctx *),
void (*move)(struct mp_ctx *, struct mp_ctx *))
void (*move)(struct mp_ctx *, struct mp_ctx *),
void (*copy)(struct mp_ctx *, struct mp_ctx *))
{
ctx->translation = translation;
ctx->destroy = destroy;
ctx->move = move;
ctx->copy = copy;
}
/**
* Default 'virtual' move: swaps the contents of @a dst and @a src.
* Default 'virtual' move: moves the contents of @a dst to @a src.
*/
void
mp_ctx_move_default(struct mp_ctx *dst, struct mp_ctx *src);
/**
* Create @a ctx with default virtual methods (i.e., `NULL` destructor and
* `mp_ctx_move_default` move).
* Default 'virtual' copy: copies the contents of @a dst to @a src.
*/
void
mp_ctx_copy_default(struct mp_ctx *dst, struct mp_ctx *src);
/**
* Create @a ctx with default virtual methods (i.e., `NULL` destructor,
* `mp_ctx_move_default` move and `mp_ctx_copy_default` copy).
*/
static inline void
mp_ctx_create_default(struct mp_ctx *ctx, struct mh_strnu32_t *translation)
......@@ -69,6 +83,7 @@ mp_ctx_create_default(struct mp_ctx *ctx, struct mh_strnu32_t *translation)
ctx->translation = translation;
ctx->destroy = NULL;
ctx->move = mp_ctx_move_default;
ctx->copy = mp_ctx_copy_default;
}
static inline void
......@@ -80,8 +95,8 @@ mp_ctx_destroy(struct mp_ctx *ctx)
}
/**
* 'Virtual' move. Provides move constructor semantics, @dst must be a default
* initialized context.
* 'Virtual' move. Provides move constructor semantics, @dst is supposed not to
* own any resources, hence it is not destroyed.
*/
static inline void
mp_ctx_move(struct mp_ctx *dst, struct mp_ctx *src)
......@@ -90,6 +105,17 @@ mp_ctx_move(struct mp_ctx *dst, struct mp_ctx *src)
src->move(dst, src);
}
/**
* 'Virtual' copy. Provides copy constructor semantics, @dst is supposed not to
* own any resources, hence it is not destroyed.
*/
static inline void
mp_ctx_copy(struct mp_ctx *dst, struct mp_ctx *src)
{
assert(src->copy != NULL);
src->copy(dst, src);
}
#if defined(__cplusplus)
} /* extern "C" */
#endif /* defined(__cplusplus) */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment