Forum: PC-Programmierung C++17, Tuples, Folding hier möglich?


von cppbert3 (Gast)


Lesenswert?

wieder mal ein sehr grosses Beispiel :/
aber vielleicht hat ja jemand eine Idee wie das gehen könnte

bisher wird der Code in make_from_c_params generiert
aber ich würde gerne den Code schlanker und weniger if/else/return 
lastiger machen - damit mein Haufen Boilerplate-Code schön klein bleibt 
:)

ich habe versucht das ganze ein wenig Template/Deklarativer zu machen - 
mir gehen aber die verrückten Ideen aus :-/

Es geht mir hier nur um eine Machbarkeit - nicht das ich da auf Teufel 
komm raus von abhängig bin - aber die Situation mit der C-Schnittstelle 
und den Error-Codes usw. ist schon sehr realistisch und kann von mir 
auch nicht verändert werden

gcc.godbolt: https://gcc.godbolt.org/z/zE7154
1
#include <vector>
2
#include <tuple>
3
#include <string>
4
5
class Test
6
{
7
private:
8
    Test() = default;
9
10
public:
11
    // "C"-Interface
12
13
    int set_id( int id_ )
14
    {
15
        m_id = id_;
16
        return 0;
17
    }
18
19
    int set_xyz( int* xyz_values_, int xyz_size_ )
20
    {
21
        if( !xyz_values_ )
22
        {
23
            return 1;
24
        }
25
        m_xyz = { xyz_values_, xyz_values_ + xyz_size_ };
26
        return 0;
27
    }
28
29
    int set_name( const char* name_ )
30
    {
31
        if( !name_ )
32
        {
33
            return 1;
34
        }
35
        m_name = name_;
36
        return 0;
37
    }
38
39
    struct result
40
    {
41
        int code{};
42
        Test* instance{};
43
    };
44
45
    //=================================
46
    // ab hier meine neuen Ideen
47
48
    friend struct create_instance;
49
50
    template <auto Set, typename... Values>
51
    struct setter
52
    {
53
        setter( Values&&... values_ ) : m_values( values_... )
54
        {
55
        }
56
        std::tuple<Values...> m_values;
57
    };
58
59
    template <typename InstanceType, typename... Setter>
60
    struct create_instance
61
    {
62
        create_instance( std::tuple<Setter...> setter_ ) : m_setter( setter_ )
63
        {
64
        }
65
66
        result operator()() const
67
        {
68
            auto instance = new Test();
69
70
            return { 0, instance };
71
        }
72
        std::tuple<Setter...> m_setter;
73
    };
74
75
    // bis hier - im #if 0 versuche ich das ganzen Aufzurufen scheitere aber
76
    // an den Parametern
77
    //=================================
78
79
    static result make_from_c_params( int id_, int* xyz_values_, int xyz_count, const char* name_ )
80
    {
81
#if 0 // ich scheitere ein wenig an den Details :/
82
        using ci = create_instance<Test, 
83
            setter<&Test::set_id>, 
84
            setter<&Test::set_xyz>, 
85
            setter<&Test::set_name>>;
86
        return ci({})();
87
        /*
88
        return create_instance<...>(instance,
89
        {
90
            {&Test::set_id, {id_}, -1}
91
            {&Test::set_xyz, {xyz_values_, xyz_count}, -2}
92
            {&Test::set_name, {name_}, -3}
93
        }
94
        );
95
        */
96
#else
97
        // dieser Code wird generiert (nur mit unique_ptr, usw.)
98
        auto instance = new Test();
99
100
        if( auto result = instance->set_id( id_ ) != 0 )
101
        {
102
            return { -1, {} };
103
        }
104
105
        if( auto result = instance->set_xyz( xyz_values_, xyz_count ) != 0 )
106
        {
107
            return { -2, {} };
108
        }
109
110
        if( auto result = instance->set_name( name_ ) != 0 )
111
        {
112
            return { -3, {} };
113
        }
114
115
        return { 0, instance };
116
#endif
117
    }
118
119
    int m_id{};
120
    std::vector<int> m_xyz;
121
    std::string m_name;
122
};
123
124
int main()
125
{
126
    int id = 12;
127
    std::vector<int> xyz{ 1, 2, 3 };
128
    std::string name = "hello";
129
    auto t = Test::make_from_c_params( id, xyz.data(), xyz.size(), name.c_str() );
130
    return 0;
131
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.