openFOAM學習筆記(三)—— char和string相關的類

openFOAM中的char和string並不是直接使用C++提供的string,而是進行了一系列的封裝,並添加了更多的功能。這裏進行一個總結。

char類型的更多功能

openFOAM中並沒有對char進行封裝,而是直接在上面添加功能。主要依賴的是如下路徑的幾個文件:

src/OpenFOAM/primitives/chars/char
char.H   charIO.C
src/OpenFOAM/primitives/chars/wchar
wchar.H   wcharIO.C

添加了readChar作爲文件流讀入的函數,以及判斷是否爲空格的isspace函數,和運算符<< >>的重定向。而charwchar的區別在於,後者使用了一個佔用字節數更高的編碼方式,所以在文件操作時的實現還需要藉助一下位運算符。

string的重新封裝

在如下路徑中

src/OpenFOAM/primitives/strings/
fileName/  keyType/  lists/  string/
stringOps/  word/  wordRe/ 

其中基礎的是string文件夾,他講std::string繼承到自己的Foam::string中。然後額外添加了靜態成員變量typeName debug null,以及一個hash類。另外定義了一系列的構造函數,用來進行初始化。代碼另外給string添加了很多功能。

//- Count and return the number of a given character in the string
//返回string的字符數
size_type count(const char) const;

//- Is this string type valid?
//判斷是否合法,主要通過比較當前迭代器的首尾位置是否與內置迭代器重合判斷
template<class String>
static inline bool valid(const string&);

//- Does this string have particular meta-characters?
//  The meta characters can be optionally quoted.
//判斷是否存在特定字符
template<class String>
static inline bool meta(const string&, const char quote='\\');

//- Strip invalid characters from the given string
//去掉其中不合法的字符,即去掉迭代器首尾之外的
template<class String>
static inline bool stripInvalid(string&);

//- Return a valid String from the given string
//返回迭代器之外的部分
template<class String>
static inline String validate(const string&);

//- Return a String with quoted meta-characters from the given string
template<class String>
static inline string quotemeta(const string&, const char quote='\\');

//- True when strings match literally
//字符匹配
inline bool match(const std::string&) const;

//- Avoid masking the normal std::string replace
//爲了避免下面的定義覆蓋原來的string
using std::string::replace;

//- Replace first occurrence of sub-string oldStr with newStr
//  starting at start
string& replace
(
            const string& oldStr,
            const string& newStr,
            size_type start = 0
);

//- Replace all occurrences of sub-string oldStr with newStr
//  starting at start
string& replaceAll
(
            const string& oldStr,
            const string& newStr,
            size_type start = 0
);

        //- Expand initial tildes and all occurrences of environment variables
        //  Expansion includes:
        //  -# environment variables
        //    - "$VAR", "${VAR}"
        //  -# current directory
        //    - leading "./" : the current directory
        //  -# tilde expansion
        //    - leading "~/" : home directory
        //    - leading "~user" : home directory for specified user
        //    - leading "~OpenFOAM" : site/user OpenFOAM configuration directory
        //
        //  Any unknown entries are removed silently if allowEmpty is true
        //  \sa
        //  Foam::findEtcFile
        string& expand(const bool allowEmpty = false);

//- Remove repeated characters returning true if string changed
//去掉重複部分
bool removeRepeated(const char);

//- Return string with repeated characters removed
//同上,但是返回值變成了string
string removeRepeated(const char) const;

//- Remove trailing character returning true if string changed
//去掉尾部字符
bool removeTrailing(const char);

//- Return string with trailing character removed
//同上,但是返回值變成了string
string removeTrailing(const char) const;

另外,<< >>被進行了重定向,方便文件流寫入string。另外,這裏定義了兩個函數

void writeEntry(Ostream& os, const char* value);
void writeEntry(Ostream& os, const string& value);

是方便用戶在未創建類的情況下進行函數的調動,也是將文件流和string進行交互。其中string\stringOps\兩個文件夾都是對這一系列功能的支持文件。

通過string創建word類

word是通過繼承當前Foam這個名字空間下的string類得到的。同樣給定了成員變量

static const char* const typeName;
static int debug;

//- An empty word
static const word null;

然後給定了一系列的構造函數,而成員函數只添加了一個

//- Is this character valid for a word
inline static bool valid(char);

其實現如下:

inline void Foam::word::stripInvalid()
{
    // skip stripping unless debug is active to avoid
    // costly operations
    if (debug && string::stripInvalid<word>(*this))
    {
        std::cerr
            << "word::stripInvalid() called for word "
            << this->c_str() << std::endl;

        if (debug > 1)
        {
            std::cerr
                << "    For debug level (= " << debug
                << ") > 1 this is considered fatal" << std::endl;
            std::abort();
        }
    }
}

我們可以看到他是通過父類string中的stripInvalid函數和自己的成員變量debug進行判斷的。而debug是通過一系列宏定義的,這裏先跳過,在後續的博客中會繼續補充。之後,當前類對運算符也進行了重定義,然後對函數writeEntry進行了多態的補充。這一系列操作在文件夾word\

但是除此之外,word相關還有一系列支持性的操作,在wordRe\中,它以word爲父類,創建了wordRe類。除去構造函數之外,還定義了一系列功能性的成員函數,
從註釋上看,主要和與字符相關的正則表達式相關。這裏不展開,在後續使用過程中用到了繼續補充。

fileName和keyType的功能

他們兩個又是以word爲父類的,然後添加了更多的功能,分別又fileName\keyType\兩個文件夾支持。

首先來看fileName,這裏的註釋給了比較好的說明:

Description
    A class for handling file names.

    A fileName is a string of characters without whitespace or quotes.
    A fileName can be
      - constructed from a char*, a string or a word
      - concatenated by adding a '/' separator
      - decomposed into the path, name or component list
      - interrogated for type and access mode

    The string::expand() method expands environment variables, etc,

就是用來存儲文件路徑的,這裏說明了構造函數的類型。另外還添加了一系列函數,總體實現的功能有:

//判斷路徑是否合法,就是a///b等這些是否會出現
inline static bool valid(char);
//清除文件路徑
fileName clean() const;
//判斷文件的類型,文件or文件夾orlinkor未知
fileType type
(
       const bool checkVariants = true,
       const bool followLink = true
) 
//判斷文件是否爲絕對路徑,以及轉換爲絕對路徑
bool isAbsolute() const;
fileName& toAbsolute();
//分解出名字
word name() const;
string caseName() const;
word name(const bool noExt) const;

另外給定了一系列運算符的重定義,和之前類似,主要是爲了方便和文件流進行交互。

我們再來看keyType,這裏的註釋也給出

Description
    A class for handling keywords in dictionaries.

    A keyType is the keyword of a dictionary.
    It differs from word in that it accepts patterns (regular expressions).

就是說我們在使用openFOAM時,常常修改的配置文件,都是用字典的形式給出的,這些字典中的字符,將會使用這個類保存。除去基礎的成員變量和構造函數外,還定義瞭如下的成員函數:

//- Should be treated as a match rather than a literal string
inline bool isPattern() const;
//- Smart match as regular expression or as a string
//  Optionally force a literal match only
bool match(const std::string&, bool literalMatch=false) const;

主要是服務於關鍵字的匹配,另外也同樣做了方便文件流使用的運算符重定義。

如上所有類的List類型

在文件夾lists\中,其中包括了當前strings\文件夾中所有類創建的List的類型重定義,比如

#include "string.H"
#include "List.H"

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

namespace Foam
{
    typedef UList<string> stringUList;

    typedef List<string> stringList;
}

就是將用string創建的ListUList重新定義爲類型stringUListstringList,其他文件的內容也是一樣的。而List的具體實現我們將在後續的博客中討論。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章