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的具体实现我们将在后续的博客中讨论。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片