1 #ifndef NETGEN_CORE_FLAGS_HPP
2 #define NETGEN_CORE_FLAGS_HPP
3 
4 
5 /**************************************************************************/
6 /* File:   flags.hpp                                                      */
7 /* Author: Joachim Schoeberl                                              */
8 /* Date:   10. Oct. 96                                                    */
9 /**************************************************************************/
10 
11 #include <iostream>
12 #include <memory>
13 #include <string>
14 #include <any>
15 
16 #include "array.hpp"
17 #include "symboltable.hpp"
18 #include "xbool.hpp"
19 
20 namespace ngcore
21 {
22 
23   /**
24       A storage for command-line flags.
25       The flag structure maintains string flags, numerical flags,
26       define flags, string list flags, num list flags.
27   */
28   class NGCORE_API Flags
29   {
30     /// string flags
31     SymbolTable<std::string> strflags;
32     /// numerical flags
33     SymbolTable<double> numflags;
34     /// define flags
35     SymbolTable<bool> defflags;
36     /// string list flags
37     SymbolTable<std::shared_ptr<Array<std::string>>> strlistflags;
38     /// numerical list flags
39     SymbolTable<std::shared_ptr<Array<double>>> numlistflags;
40     /// flags list flags
41     SymbolTable<Flags> flaglistflags;
42     /// any object can be stored as a flag
43     SymbolTable<std::any> anyflags;
44   public:
45     /// no flags
46     Flags ();
47     /// copy flags
48     Flags (const Flags & flags);
49     /// steal flags
50     Flags (Flags && flags);
51     ///
52     Flags (std::initializer_list<std::string> list);
53     ///
54     Flags (std::string f1, std::string f2 = "", std::string f3 = "", std::string f4 = "", std::string f5 = "");
55     /// delete mem
56     ~Flags ();
57 
58     Flags & operator= (const Flags & f2) = default;
59     Flags & operator= (Flags && f2) = default;
60 
61     void DoArchive(Archive& ar);
62 
63     void Update(const Flags& other);
64 
65     /// Deletes all flags
66     void DeleteFlags ();
67 
68     /// Sets string flag, overwrite if exists
69     Flags & SetFlag (const char * name, const std::string & val);
70     /// Sets string flag, overwrite if exists
SetFlag(const char * name,const char * str)71     Flags & SetFlag (const char * name, const char * str)
72     { return SetFlag (name, std::string(str)); }
73     /// Sets numerical flag, overwrite if exists
74     Flags & SetFlag (const char * name, double val) &;
75     /// Sets numerical flag, overwrite if exists
SetFlag(const char * name,int val)76     Flags & SetFlag (const char * name, int val)
77     { return SetFlag (name, double(val)); }
78     /// Sets boolean flag
79     Flags & SetFlag (const char * name, bool b = true) &;
80     /// Sets numerical flag, overwrite if exists
81     Flags & SetFlag (const char * name, Flags & val) &;
82 
83     /// Sets string flag, overwrite if exists
84     Flags & SetFlag (const std::string & name, const std::string & val);
SetFlag(const std::string & name,const char * str)85     Flags & SetFlag (const std::string & name, const char * str)
86     { return SetFlag (name, std::string(str)); }
87     /// Sets numerical flag, overwrite if exists
88     Flags &  SetFlag (const std::string & name, double val);
89     /// Sets numerical flag, overwrite if exists
SetFlag(const std::string & name,int val)90     Flags &  SetFlag (const std::string & name, int val)
91     { return SetFlag (name, double(val)); }
92     /// Sets boolean flag
93     Flags &  SetFlag (const std::string & name, bool b = true);
94     /// Sets numerical flag, overwrite if exists
95     Flags &  SetFlag (const std::string & name, Flags & val);
96     /// Sets string array flag
97     Flags &  SetFlag (const std::string & name, const Array<std::string> & val);
98     /// Sets double array flag
99     Flags &  SetFlag (const std::string & name, const Array<double> & val);
100     /// Sets any flag
101     Flags &  SetFlag(const std::string& name, const std::any& val);
102 
103 
104     Flags SetFlag (const char * name, bool b = true) &&;
105     Flags SetFlag (const char * name, double val) &&;
106 
107 
108 
109     /// Save flags to file
110     void SaveFlags (const char * filename) const;
111     void SaveFlags (ostream & str) const;
112     /// write flags to stream
113     void PrintFlags (ostream & ost) const;
114     /// Load flags from file
115     void LoadFlags (const char * filename, SymbolTable<Flags> * sf = nullptr);
116     void LoadFlags (std::istream & str, SymbolTable<Flags> * sf = nullptr);
117     /**
118        Set command line flag.
119        Flag must be in form: -name=hello -val=0.5 -defflag
120        -names=[Joe,Jim] -values=[1,3,4] -solverflags=*abc
121     */
122     void SetCommandLineFlag (const char * st, SymbolTable<Flags> * sf = nullptr);
123     /// Returns string flag, default value if not exists
124     std::string GetStringFlag (const std::string & name, const char * def) const;
125     /// Returns std::string flag, default value if not exists
126     std::string GetStringFlag (const std::string & name, std::string def = "") const;
127     /// Returns numerical flag, default value if not exists
128     double GetNumFlag (const std::string & name, double def) const;
129     /// Returns address of numerical flag, null if not exists
130     const double * GetNumFlagPtr (const std::string & name) const;
131     /// Returns address of numerical flag, null if not exists
132     double * GetNumFlagPtr (const std::string & name);
133     /// Returns boolean flag
134     // int GetDefineFlag (const char * name) const;
135     bool GetDefineFlag (const std::string & name) const throw();
136     xbool GetDefineFlagX (const std::string & name) const throw();
137     /// Returns string list flag, empty array if not exist
138     const Array<std::string> & GetStringListFlag (const std::string & name) const;
139     /// Returns num list flag, empty array if not exist
140     const Array<double> & GetNumListFlag (const std::string & name) const;
141     /// Returns flag list flag, empty flag if not exist
142     const Flags & GetFlagsFlag (const std::string & name) const;
143     const std::any& GetAnyFlag (const std::string& name) const;
144 
145 
146     /// Test, if string flag is defined
147     bool StringFlagDefined (const std::string & name) const;
148     /// Test, if num flag is defined
149     bool NumFlagDefined (const std::string & name) const;
150     /// Test, if num flag is defined
151     bool FlagsFlagDefined (const std::string & name) const;
152     /// Test, if string list flag is defined
153     bool StringListFlagDefined (const std::string & name) const;
154     /// Test, if num list flag is defined
155     bool NumListFlagDefined (const std::string & name) const;
156     bool AnyFlagDefined (const std::string& name) const;
157 
158     /// number of string flags
GetNStringFlags() const159     int GetNStringFlags () const { return strflags.Size(); }
160     /// number of num flags
GetNNumFlags() const161     int GetNNumFlags () const { return numflags.Size(); }
162     /// number of num flags
GetNFlagsFlags() const163     int GetNFlagsFlags () const { return flaglistflags.Size(); }
164     /// number of define flags
GetNDefineFlags() const165     int GetNDefineFlags () const { return defflags.Size(); }
166     /// number of string-list flags
GetNStringListFlags() const167     int GetNStringListFlags () const { return strlistflags.Size(); }
168     /// number of num-list flags
GetNNumListFlags() const169     int GetNNumListFlags () const { return numlistflags.Size(); }
GetNAnyFlags() const170     int GetNAnyFlags() const { return anyflags.Size(); }
171 
172     ///
GetStringFlag(int i,std::string & name) const173     const std::string & GetStringFlag (int i, std::string & name) const
174     { name = strflags.GetName(i); return strflags[i]; }
GetNumFlag(int i,std::string & name) const175     double GetNumFlag (int i, std::string & name) const
176     { name = numflags.GetName(i); return numflags[i]; }
GetDefineFlag(int i,std::string & name) const177     bool GetDefineFlag (int i, std::string & name) const
178     { name = defflags.GetName(i); return defflags[i]; }
GetNumListFlag(int i,std::string & name) const179     const std::shared_ptr<Array<double>> GetNumListFlag (int i, std::string & name) const
180     { name = numlistflags.GetName(i).c_str(); return numlistflags[i]; }
GetStringListFlag(int i,std::string & name) const181     const std::shared_ptr<Array<std::string>> GetStringListFlag (int i, std::string & name) const
182     { name = strlistflags.GetName(i); return strlistflags[i]; }
GetFlagsFlag(int i,std::string & name) const183     const Flags & GetFlagsFlag (int i, std::string & name) const
184     { name = flaglistflags.GetName(i); return flaglistflags[i]; }
GetAnyFlag(int i,std::string & name) const185     const std::any& GetAnyFlag(int i, std::string& name) const
186     { name = anyflags.GetName(i); return anyflags[i]; }
187   };
188 
189   /// Print flags
operator <<(std::ostream & s,const Flags & flags)190   inline std::ostream & operator<< (std::ostream & s, const Flags & flags)
191   {
192     flags.PrintFlags (s);
193     return s;
194   }
195 } // namespace ngcore
196 
197 
198 #endif // NETGEN_CORE_FLAGS_HPP
199 
200