openFOAM代碼閱讀——基礎代碼中的string

代碼仍然是src/OpenFOAM/primitives/路徑中的,爲文件夾strings,其中有內容

fileName keyType lists string stringOps word wordRe

這裏的多個文件夾都使用到了這裏的word文件夾中的文件,而word用到了string中的內容,所以我們先讀這個吧。這裏包含了如下幾個文件:

string.C string.H stringI.H stringIO.C stringIOList.C stringIOList.H

string.H開始讀,正文太長了我們分段放出來讀:

/*Description
    A class for handling character strings derived from std::string.

    Strings may contain any characters and therefore are delimited by quotes
    for IO : "any list of characters".

    Used as a base class for word and fileName.

See also
    Foam::findEtcFile() for information about the site/user OpenFOAM
    configuration directory

SourceFiles
    string.C
    stringIO.C
---------------------------------------------------------------------------*/
#include "char.H"
#include "Hasher.H"

#include <string>
#include <cstring>
#include <cstdlib>

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

這裏使用到的char.H頭文件前面已經度過了,就是給Foam名字域下的IstreamOstream提供運算符重定義和readChar函數。Hasher.H頭文件在路徑~/OpenFOAM/OpenFOAM-7/src/OpenFOAM/primitives/hashes中,主要是代碼實現了哈希的功能,我們之後會仔細閱讀。

Description中描述了當前文件定義的類的功能,主要處理std::string的字符串。另外字符串因爲可能包含多種符號,所以要用雙引號

namespace Foam
{

// Forward declaration of classes
class Istream;
class Ostream;

// Forward declaration of friend functions and operators
class string;
Istream& operator>>(Istream&, string&);
Ostream& operator<<(Ostream&, const string&);
Ostream& operator<<(Ostream&, const std::string&);

類似前面幾個博客中閱讀的,這裏也是對>><<進行重定向,這裏把多態擴展到了string。下面爲類的聲明,爲一系列的構造函數和成員函數,以及操作符重載。

/*---------------------------------------------------------------------------*\
                           Class string Declaration
\*---------------------------------------------------------------------------*/

class string
:
    public std::string
{
public:

    // Static Data Members

        static const char* const typeName;
        static int debug;

        //- An empty string
        static const string null;


    //- Hashing function class, shared by all the derived classes
    class hash
    {
    public:
        hash()
        {}

        inline unsigned operator()(const string&, unsigned seed = 0) const;
    };


    // Constructors

        //- Construct null 
        inline string();

        ...


    // Member Functions

        //- Count and return the number of a given character in the string
        size_type count(const char) const;

       ...


    // Member Operators

        //- Return the sub-string from the i-th character for \a n characters
        inline string operator()
        (
            const size_type i,
            const size_type n
        ) const;

        //- Return the sub-string from the first character for \a n characters
        inline string operator()
        (
            const size_type n
        ) const;

        inline void operator=(const string&);
        inline void operator=(string&&);


    // IOstream Operators

        friend Istream& operator>>(Istream&, string&);
        friend Ostream& operator<<(Ostream&, const string&);
};


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


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

} // End namespace Foam

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

#include "stringI.H"

這裏的stringI.H來自相同文件夾,其實是上述文件中所有inline函數的具體實現,基本上都是通過直接調用std名字域中的string變量來。而其餘函數的具體實現,在string.C中。(話說爲啥不直接用std::string)。具體可以使用的成員函數如下:

valid(const string& str)   判斷是否合法
meta(const string&, const char quote='\\')   判斷string是否含有特定的字符串
stripInvalid(string& str)  裁掉不合法的部分
validate(const string&)   從給定string中給出一個合法的string
quotemeta(const string&, const char quote='\\')  返回帶有特定字符串的字符串
replace(const string& oldStr,const string& newStr,size_type start = 0) 替換
replaceAll(const string& oldStr,const string& newStr,size_type start = 0)  全部替換
...

string()(const size_type i,const size_type n) 從第i個開始的n個字符
string()(const size_type n)  從頭開始的n個字符
operator=(const string&);  賦值
operator=(string&&);         賦值
>> <<的重定義和之前一致

這裏還用到了stringOps.H,位於strings/stringOps/文件夾中,之後再去閱讀。

我們接下來看另外一組文件,首先從stringIOList.H開始,內容如下:

#include "stringList.H"
#include "IOList.H"

namespace Foam
{
    typedef IOList<string> stringIOList;
    typedef IOList<stringList> stringListIOList;
}

定義了兩個類型stringIOListstringListIOList,即分別以stringstringList類型生成的IOList。而IOList類型的聲明在IOList.H中,路徑src/OpenFOAM/db/IOobjects/IOList/IOList.H

我們之後再去閱讀stringIO.C,內容如下,我直接將函數的功能註釋在代碼中:

#include "string.H"
#include "IOstreams.H"

// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //

Foam::string::string(Istream& is)
{
    is >> *this; //將is中讀取的字符串,保存在當前string對象中
}


// * * * * * * * * * * * * * * * IOstream Functions  * * * * * * * * * * * * //
//注意這些普通函數,不是某個類的成員函數
void Foam::writeEntry(Ostream& os, const char* value)
{
    os << value; //將char數組輸出
}


void Foam::writeEntry(Ostream& os, const string& value)
{
    os << value; //將string輸出
}


// * * * * * * * * * * * * * * * IOstream Operators  * * * * * * * * * * * * //

Foam::Istream& Foam::operator>>(Istream& is, string& s)
{
    token t(is);

    if (!t.good())
    {
        is.setBad();
        return is;
    }

    if (t.isString())
    {
        s = t.stringToken();
    }
    else
    {
        is.setBad();
        FatalIOErrorInFunction(is)
            << "wrong token type - expected string, found " << t.info()
            << exit(FatalIOError);

        return is;
    }

    // Check state of Istream
    is.check("Istream& operator>>(Istream&, string&)");

    return is;
}

//string意義下的運算符重定義,類似之前對char進行的工作
Foam::Ostream& Foam::operator<<(Ostream& os, const string& s)
{
    os.write(s);
    os.check("Ostream& operator<<(Ostream&, const string&)");
    return os;
}


Foam::Ostream& Foam::operator<<(Ostream& os, const std::string& s)
{
    os.write(string(s));
    os.check("Ostream& operator<<(Ostream&, const std::string&)");
    return os;
}

最後一個文件stringIOList.C這裏正文似乎對幾個函數進行了聲明,但是並未給出實現,再後續閱讀讀到了會在這裏補齊

{
    defineCompoundTypeName(List<string>, stringList);
    addCompoundToRunTimeSelectionTable(List<string>, stringList);

    defineTemplateTypeNameAndDebugWithName(stringIOList, "stringList", 0);
    defineTemplateTypeNameAndDebugWithName
    (
        stringListIOList,
        "stringListList",
        0
    );
}

呃,後面稍微改一下形式吧,貼代碼講解的形式,不如直接在代碼上註釋。之後會在總結完一個模塊後,集中說明模塊的作用

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