aboutsummaryrefslogtreecommitdiff
path: root/args.hxx
blob: 442b2a9f4582360324b7def171117b6167174a86 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/* Copyright © 2016 Taylor C. Richberger <taywee@gmx.com>
 * This code is released under the license described in the LICENSE file
 */

#include <string>
#include <vector>
#include <list>
#include <functional>

namespace args
{
    class Base
    {
        protected:
            bool matched;

        public:
            Base() : matched(false) {}
            virtual ~Base() {}

            virtual bool Matched() const
            {
                return matched;
            }
    };

    class Group : public Base
    {
        private:
            std::vector<Base*> children;
            std::function<bool(int, int)> validator;

        public:

            Group(const std::function<bool(int, int)> &validator = Validators::DontCare) : validator(validator) {}
            virtual ~Group() {}

            void Add(Base &child)
            {
                children.emplace_back(&child);
            }

            int MatchedChildren() const
            {
                int sum = 0;
                for (const Base * child: children)
                {
                    if (child->Matched())
                    {
                        ++sum;
                    }
                }
                return sum;
            }

            virtual bool Matched() const override
            {
                return validator(children.size(), MatchedChildren());
            }

            struct Validators
            {
                static bool Xor(int children, int matched)
                {
                    return matched == 1;
                }

                static bool AtLeastOne(int children, int matched)
                {
                    return matched >= 1;
                }

                static bool AtMostOne(int children, int matched)
                {
                    return matched <= 1;
                }

                static bool All(int children, int matched)
                {
                    return children == matched;
                }

                static bool DontCare(int children, int matched)
                {
                    return true;
                }

                static bool CareTooMuch(int children, int matched)
                {
                    return false;
                }

                static bool None(int children, int matched)
                {
                    return matched == 0;
                }
            };
    };

    class ArgumentParser
    {
        private:
            std::string prog;
            std::string description;
            std::string epilog;

            Group args;

        public:
            ArgumentParser(
                const std::string &prog,
                const std::string &description,
                const std::string &epilog = std::string()) : prog(prog), description(description), epilog(epilog) {}

            void ParseArgs(const std::vector<std::string> &args)
            {
            }

            void ParseCLI(const int argc, const char * const * const argv)
            {
                std::vector<std::string> args;
                for (int i = 1; i < argc; ++i)
                {
                    args.emplace_back(argv[i]);
                }
                ParseArgs(args);
            }
    };
}