netgen/libsrc/core/flags.hpp

200 lines
7.8 KiB
C++

#ifndef NETGEN_CORE_FLAGS_HPP
#define NETGEN_CORE_FLAGS_HPP
/**************************************************************************/
/* File: flags.hpp */
/* Author: Joachim Schoeberl */
/* Date: 10. Oct. 96 */
/**************************************************************************/
#include <iostream>
#include <memory>
#include <string>
#include <any>
#include "array.hpp"
#include "symboltable.hpp"
#include "xbool.hpp"
namespace ngcore
{
/**
A storage for command-line flags.
The flag structure maintains string flags, numerical flags,
define flags, string list flags, num list flags.
*/
class NGCORE_API Flags
{
/// string flags
SymbolTable<std::string> strflags;
/// numerical flags
SymbolTable<double> numflags;
/// define flags
SymbolTable<bool> defflags;
/// string list flags
SymbolTable<std::shared_ptr<Array<std::string>>> strlistflags;
/// numerical list flags
SymbolTable<std::shared_ptr<Array<double>>> numlistflags;
/// flags list flags
SymbolTable<Flags> flaglistflags;
/// any object can be stored as a flag
SymbolTable<std::any> anyflags;
public:
/// no flags
Flags ();
/// copy flags
Flags (const Flags & flags);
/// steal flags
Flags (Flags && flags);
///
Flags (std::initializer_list<std::string> list);
///
Flags (std::string f1, std::string f2 = "", std::string f3 = "", std::string f4 = "", std::string f5 = "");
/// delete mem
~Flags ();
Flags & operator= (const Flags & f2) = default;
Flags & operator= (Flags && f2) = default;
void DoArchive(Archive& ar);
void Update(const Flags& other);
/// Deletes all flags
void DeleteFlags ();
/// Sets string flag, overwrite if exists
Flags & SetFlag (const char * name, const std::string & val);
/// Sets string flag, overwrite if exists
Flags & SetFlag (const char * name, const char * str)
{ return SetFlag (name, std::string(str)); }
/// Sets numerical flag, overwrite if exists
Flags & SetFlag (const char * name, double val) &;
/// Sets numerical flag, overwrite if exists
Flags & SetFlag (const char * name, int val)
{ return SetFlag (name, double(val)); }
/// Sets boolean flag
Flags & SetFlag (const char * name, bool b = true) &;
/// Sets numerical flag, overwrite if exists
Flags & SetFlag (const char * name, Flags & val) &;
/// Sets string flag, overwrite if exists
Flags & SetFlag (const std::string & name, const std::string & val);
Flags & SetFlag (const std::string & name, const char * str)
{ return SetFlag (name, std::string(str)); }
/// Sets numerical flag, overwrite if exists
Flags & SetFlag (const std::string & name, double val);
/// Sets numerical flag, overwrite if exists
Flags & SetFlag (const std::string & name, int val)
{ return SetFlag (name, double(val)); }
/// Sets boolean flag
Flags & SetFlag (const std::string & name, bool b = true);
/// Sets numerical flag, overwrite if exists
Flags & SetFlag (const std::string & name, Flags & val);
/// Sets string array flag
Flags & SetFlag (const std::string & name, const Array<std::string> & val);
/// Sets double array flag
Flags & SetFlag (const std::string & name, const Array<double> & val);
/// Sets any flag
Flags & SetFlag(const std::string& name, const std::any& val);
Flags SetFlag (const char * name, bool b = true) &&;
Flags SetFlag (const char * name, double val) &&;
/// Save flags to file
void SaveFlags (const char * filename) const;
void SaveFlags (ostream & str) const;
/// write flags to stream
void PrintFlags (ostream & ost) const;
/// Load flags from file
void LoadFlags (const char * filename, SymbolTable<Flags> * sf = nullptr);
void LoadFlags (std::istream & str, SymbolTable<Flags> * sf = nullptr);
/**
Set command line flag.
Flag must be in form: -name=hello -val=0.5 -defflag
-names=[Joe,Jim] -values=[1,3,4] -solverflags=*abc
*/
void SetCommandLineFlag (const char * st, SymbolTable<Flags> * sf = nullptr);
/// Returns string flag, default value if not exists
std::string GetStringFlag (const std::string & name, const char * def) const;
/// Returns std::string flag, default value if not exists
std::string GetStringFlag (const std::string & name, std::string def = "") const;
/// Returns numerical flag, default value if not exists
double GetNumFlag (const std::string & name, double def) const;
/// Returns address of numerical flag, null if not exists
const double * GetNumFlagPtr (const std::string & name) const;
/// Returns address of numerical flag, null if not exists
double * GetNumFlagPtr (const std::string & name);
/// Returns boolean flag
// int GetDefineFlag (const char * name) const;
bool GetDefineFlag (const std::string & name) const throw();
xbool GetDefineFlagX (const std::string & name) const throw();
/// Returns string list flag, empty array if not exist
const Array<std::string> & GetStringListFlag (const std::string & name) const;
/// Returns num list flag, empty array if not exist
const Array<double> & GetNumListFlag (const std::string & name) const;
/// Returns flag list flag, empty flag if not exist
const Flags & GetFlagsFlag (const std::string & name) const;
const std::any& GetAnyFlag (const std::string& name) const;
/// Test, if string flag is defined
bool StringFlagDefined (const std::string & name) const;
/// Test, if num flag is defined
bool NumFlagDefined (const std::string & name) const;
/// Test, if num flag is defined
bool FlagsFlagDefined (const std::string & name) const;
/// Test, if string list flag is defined
bool StringListFlagDefined (const std::string & name) const;
/// Test, if num list flag is defined
bool NumListFlagDefined (const std::string & name) const;
bool AnyFlagDefined (const std::string& name) const;
/// number of string flags
int GetNStringFlags () const { return strflags.Size(); }
/// number of num flags
int GetNNumFlags () const { return numflags.Size(); }
/// number of num flags
int GetNFlagsFlags () const { return flaglistflags.Size(); }
/// number of define flags
int GetNDefineFlags () const { return defflags.Size(); }
/// number of string-list flags
int GetNStringListFlags () const { return strlistflags.Size(); }
/// number of num-list flags
int GetNNumListFlags () const { return numlistflags.Size(); }
int GetNAnyFlags() const { return anyflags.Size(); }
///
const std::string & GetStringFlag (int i, std::string & name) const
{ name = strflags.GetName(i); return strflags[i]; }
double GetNumFlag (int i, std::string & name) const
{ name = numflags.GetName(i); return numflags[i]; }
bool GetDefineFlag (int i, std::string & name) const
{ name = defflags.GetName(i); return defflags[i]; }
const std::shared_ptr<Array<double>> GetNumListFlag (int i, std::string & name) const
{ name = numlistflags.GetName(i).c_str(); return numlistflags[i]; }
const std::shared_ptr<Array<std::string>> GetStringListFlag (int i, std::string & name) const
{ name = strlistflags.GetName(i); return strlistflags[i]; }
const Flags & GetFlagsFlag (int i, std::string & name) const
{ name = flaglistflags.GetName(i); return flaglistflags[i]; }
const std::any& GetAnyFlag(int i, std::string& name) const
{ name = anyflags.GetName(i); return anyflags[i]; }
};
/// Print flags
inline std::ostream & operator<< (std::ostream & s, const Flags & flags)
{
flags.PrintFlags (s);
return s;
}
} // namespace ngcore
#endif // NETGEN_CORE_FLAGS_HPP