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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
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
}

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.