matus-chochlik / std_cpp_refl

Proposal to add static reflection to C++
14 stars 2 forks source link

Typedef (alias) reflection #9

Open matus-chochlik opened 8 years ago

matus-chochlik commented 8 years ago

Let's have the following:

enum E { x, y, z };

typedef F E;
typedef F G;

template <typename T>
struct S {
    typedef T type;
    typedef reflexpr(T) mtype;
    T x;
    void foo(void);
};

Alternatives for alias reflection:

A) (my new favorite)

Concepts:

For reflected typedef both a /meta-Alias/ and a /meta-Aliased/ are also a /meta-Type/ so all type-related operations apply to them, just like a /typedef/ is still a /type/.

Operations:

Rules:

using MAs = reflexpr(std::size_t); // (always a) meta-Alias

also:

template <typename T>
void S<T>::foo(void) {
    using MTp = reflexpr(T); // meta-TemplateParameter (meta-Alias)
}
using MAs = reflexpr(std::size_t); // meta-Alias
get_name_v<MAs>; // "size_t"

template <typename T>
void S<T>::foo(void) {
    using MTp = reflexpr(T); // meta-TemplateParameter (meta-Alias)
    get_name_v<MTp>; // "T"
}
using MAs = reflexpr(std::size_t); // meta-Alias
using MAd = get_aliased_m<MAs>; // meta-Aliased
get_name_v<MAd>; // "unsigned" (or whatever)
void S<G>::foo(void) {
    using Mx = reflexpr(x); // meta-DataMember
    using MT = get_type_m<Mx>; // meta-Type (possibly meta-Aliased)
    constexpr_if(Aliased<MT>) {
        using MAs = get_alias_m<MT>; // meta-Alias (explicitly obtained from a meta-Aliased)
        get_name_v<MAs>; // "T" -- the 'topmost' alias name
    } constexpr_else {
        get_name_v<MT>; // "E" -- the most basic type name
    }
}

Pros: The /meta-Alias/ ties together information about:

and it allows to use the same functions as with /meta-Named/ -- no duplication:

using MetaNamed = reflexpr(S<G>::type);
using MetaAliasT = S<G>::mtype;
using MetaAliasG = reflexpr(G);

get_name_v<MetaNamed> // "E" (since: type -> T -> G -> F -> E)
get_name_v<MetaAliasT> // "T"
get_name_v<MetaAliasG> // "G"

get_scope_m<MetaNamed> // the global scope
get_scope_m<MetaAliasT> // the S<G> class
get_scope_m<MetaAliasG> // the global scope

get_source_line_v<MetaNamed> // 8
get_source_line_v<MetaAliasT>   // 6
get_source_line_v<MetaAliasG>  // 4

TODO: to be finished

ricardofandrade commented 8 years ago

A few questions that can be responded when the TODO is taken care of: