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

tuple of tuple using global oplist #20

Closed
mario-tux opened this issue Aug 18, 2018 · 8 comments
Closed

tuple of tuple using global oplist #20

mario-tux opened this issue Aug 18, 2018 · 8 comments
Assignees
Labels

Comments

@mario-tux
Copy link

I'm trying to switch my code to use the possibility to use globally defined oplists without specification during definition of containers and related oplist declaration. I guessed this new feature from the commit names: is it missing in README.md?

During such switch I think I've found some kind of bug. I'm able to define an array of tuples like this:

TUPLE_DEF2(my_tuple, (name, string_t), (value, int))
#define M_OPL_my_tuple_t() TUPLE_OPLIST(my_tuple)

ARRAY_DEF(my_list_of_tuple, my_tuple_t)
#define M_OPL_my_list_of_tuple_t() ARRAY_OPLIST(my_list_of_tuple)

but at this point I can't define a tuple containing another tuple:

TUPLE_DEF2(my_tuple_of_tuple, (name, string_t), (inner_tuple, my_tuple_t))
#define M_OPL_my_tuple_of_tuple_t() TUPLE_OPLIST(my_tuple_of_tuple)

I get an error like: error: use of undeclared identifier 'm_no_default_function'

I've not tested other combinations of containers.

@P-p-H-d P-p-H-d self-assigned this Aug 18, 2018
@P-p-H-d P-p-H-d added the bug label Aug 18, 2018
@P-p-H-d
Copy link
Owner

P-p-H-d commented Aug 18, 2018

I can reproduce the issue.
I have a precise idea why it fails and it is a nasty bug (recursive call of M_REDUCE2 that fails to expand properly on its second invocation). I'll think about which is the best solution to fix this properly.

Thanks for the report!

@P-p-H-d
Copy link
Owner

P-p-H-d commented Aug 19, 2018

The issue should be solved in master.
If it works fine, I'll back-port the fix to the variant.

@mario-tux
Copy link
Author

Ok, I can confirm that it fixes the toy example and my bigger code.

A question: if I understood I can omit the oplist specifications also in macros like TUPLE_OPLIST (like in the toy example above). Right?

If this is true I think that another bug is raising: it looks related to the automatic definition of the out_str method (with container elements supporting it). I'll try to create another related toy example.

@mario-tux
Copy link
Author

Here the example for the second bug:

TUPLE_DEF2(my_tuple, (name, string_t), (value, int))
#define M_OPL_my_tuple_t() TUPLE_OPLIST(my_tuple)

ARRAY_DEF(my_list_of_tuple, my_tuple_t)
#define M_OPL_my_list_of_tuple_t() ARRAY_OPLIST(my_list_of_tuple)

TUPLE_DEF2(my_tuple_of_tuple, (name, string_t), (inner_tuple, my_tuple_t))
#define M_OPL_my_tuple_of_tuple_t() TUPLE_OPLIST(my_tuple_of_tuple)

int main() {
    M_LET(t, my_tuple_t)
    M_LET(lt, my_list_of_tuple_t)
    M_LET(tt, my_tuple_of_tuple_t) {
        my_tuple_out_str(stdout, t);
        my_list_of_tuple_out_str(stdout, lt);
        my_tuple_of_tuple_out_str(stdout, tt);
    }
}

Here the methods my_list_of_tuple_out_str/my_tuple_of_tuple_out_str are not defined. If I use the specific OPLISTs for the former tuple (#define M_OPL_my_tuple_t() TUPLE_OPLIST(my_tuple, STRING_OPLIST, M_DEFAULT_OPLIST) then the methods are defined.

@P-p-H-d
Copy link
Owner

P-p-H-d commented Aug 19, 2018

You cannot omit the oplist specifications in macros like TUPLE_OPLIST. Otherwise this macro will be conservative and will only provide the interfaces that are always defined by the tuples. This is true for all _OPLIST macro. Unfortunately, I don't know any way to avoid this constraint.

I plan to add support for types in _OPLIST alongside oplist (so that it will try to get a global defined one), but it is not supported yet.

@mario-tux
Copy link
Author

Ok, but I don't understand why the following example looks to work even if the last two OPLISTs are defined without further specifications:

TUPLE_DEF2(my_tuple, (name, string_t), (value, int))
#define M_OPL_my_tuple_t() TUPLE_OPLIST(my_tuple, STRING_OPLIST, M_DEFAULT_OPLIST

ARRAY_DEF(my_list_of_tuple, my_tuple_t)
#define M_OPL_my_list_of_tuple_t() ARRAY_OPLIST(my_list_of_tuple)

TUPLE_DEF2(my_tuple_of_tuple, (name, string_t), (inner_tuple, my_tuple_t))
#define M_OPL_my_tuple_of_tuple_t() TUPLE_OPLIST(my_tuple_of_tuple)

int main() {
    M_LET(t, my_tuple_t)
    M_LET(lt, my_list_of_tuple_t)
    M_LET(tt, my_tuple_of_tuple_t) {
        my_tuple_out_str(stdout, t);
        my_list_of_tuple_out_str(stdout, lt);
        my_tuple_of_tuple_out_str(stdout, tt);
    }
}

In this case the _out_str methods looks defined...

@P-p-H-d
Copy link
Owner

P-p-H-d commented Aug 19, 2018

The only interface that will read the oplists defined by M_OPL_my_list_of_tuple_t() and M_OPL_my_tuple_of_tuple_t() is the macro M_LET. M_LET only needs an interface that provides the INIT & CLEAR & TYPE operators. And all oplist provide the methods of theses operators. Therefore, you can omit it in this case and it will still work.
An OPLIST only provides to other the interface of the defined type itself. The type and its functions are defined by the macro _DEF, and this macro only needs the oplists of its sub types to decide which function to define, and doesn't need at all the upper OPLIST.

In summary:

/* This will define my_tuple_of_tuple_out_str as string_t exports an OUT_STR method and my_tuple_t exports one too */
TUPLE_DEF2(my_tuple_of_tuple, (name, string_t), (inner_tuple, my_tuple_t))
/* This will not export the defined OUT_STR method to other interfaces */
#define M_OPL_my_tuple_of_tuple_t() TUPLE_OPLIST(my_tuple_of_tuple)

However, I think it is safer to always define the OPLIST with the proper sub-oplists.

@mario-tux
Copy link
Author

Ok, thanks for the details. Closing this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants