[ox] Add strings section to docs
All checks were successful
Build / build (push) Successful in 1m11s
All checks were successful
Build / build (push) Successful in 1m11s
This commit is contained in:
163
deps/ox/ox-docs.md
vendored
163
deps/ox/ox-docs.md
vendored
@@ -181,6 +181,169 @@ variant for creating a non-const value.
|
|||||||
|
|
||||||
* ```OX_REQUIRE_M``` - OX_REQUIRE Mutable
|
* ```OX_REQUIRE_M``` - OX_REQUIRE Mutable
|
||||||
|
|
||||||
|
### Ox String Types
|
||||||
|
|
||||||
|
Ox has six different major string types.
|
||||||
|
These types are divided into two categories: store types and view types.
|
||||||
|
|
||||||
|
String stores maintain a copy of the string data, whereas view types only
|
||||||
|
maintain a reference to the data.
|
||||||
|
Views should be used where you otherwise might use a const reference to a
|
||||||
|
string store type.
|
||||||
|
|
||||||
|
#### String Store Types
|
||||||
|
|
||||||
|
##### String
|
||||||
|
|
||||||
|
```ox::String```, or really ```ox::BasicString```, is Ox's version of
|
||||||
|
```std::string```.
|
||||||
|
Like ```std::string```, ```String``` allocates to store the string data.
|
||||||
|
Also like ```std::string```, ```String``` allows for small string
|
||||||
|
optimization for strings under 8 bytes.
|
||||||
|
Unlike ```std::string```, the template that ```String``` is based on,
|
||||||
|
```BasicString```, takes a parameter that allows adjusting to different size
|
||||||
|
small string buffers.
|
||||||
|
```ox::String``` is an alias to ```ox::BasicString<8>```.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// s can hold up to 100 bytes, plus one for a null terminator before allocating
|
||||||
|
ox::BasicString<100> s;
|
||||||
|
```
|
||||||
|
Also ulike ```std::string```, ```String``` has an explicit C-string conversion
|
||||||
|
constructor.
|
||||||
|
This prevents accidental instantiations of ```String```.
|
||||||
|
|
||||||
|
Consider the following:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
void fStd(std::string const&);
|
||||||
|
void fOx(ox::String const&);
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
// implicit and silent instantiation of std::string, which includes an
|
||||||
|
// allocation
|
||||||
|
fStd("123456789");
|
||||||
|
// Will fail to compile:
|
||||||
|
fOx("123456789");
|
||||||
|
// But explicit String instantiation will work:
|
||||||
|
fOx(ox::String{"123456789"});
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
##### IString
|
||||||
|
|
||||||
|
```IString```, or "inline string", is like ```BasicString```, but it will cut
|
||||||
|
off strings that exceed that limit.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
ox::IString<5> s; // s can hold up to 5 characters, plus a null terminator
|
||||||
|
s = "12345"; // valid
|
||||||
|
s = "123456"; // will compile and run, but will get cut off at '5'
|
||||||
|
```
|
||||||
|
|
||||||
|
##### StringParam
|
||||||
|
|
||||||
|
```StringParam``` is a weird type.
|
||||||
|
Because ```String::String(const char*)``` is explicit, it becomes a pain for
|
||||||
|
functions to take ```String```s.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
struct Type {
|
||||||
|
ox::String m_s;
|
||||||
|
explicit Type(ox::String p): m_s(std::move(p)) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void f() {
|
||||||
|
ox::String s{"asdf"};
|
||||||
|
Type t1{"asdf"}; // invalid - will not compile
|
||||||
|
Type t2{s}; // invalid - will not compile
|
||||||
|
Type t3{std::move(s)}; // valid
|
||||||
|
Type t4{ox::String{"asdf"}}; // valid
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```StringParam``` has implicit conversion constructors, and will appropriately
|
||||||
|
move from r-value ```String```s.
|
||||||
|
It will create a ```String``` if not passed ownership of an existing
|
||||||
|
```String```.
|
||||||
|
|
||||||
|
```StringParam``` can access the string as a view through the ```view()```
|
||||||
|
function, and the ```String``` inside can be accessed by moving from the
|
||||||
|
```StringParams```.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
struct Type {
|
||||||
|
ox::String m_s;
|
||||||
|
explicit Type(ox::StringParam p): m_s(std::move(p)) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void f() {
|
||||||
|
ox::String s{"asdf"};
|
||||||
|
Type t1{"asdf"}; // valid
|
||||||
|
Type t2{s}; // valid
|
||||||
|
Type t3{std::move(s)}; // valid
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### String View Types
|
||||||
|
|
||||||
|
##### StringView
|
||||||
|
|
||||||
|
```ox::StringView``` is Ox's version of ```std::string_view```.
|
||||||
|
```StringView``` contains a pointer to a string, along with its size.
|
||||||
|
|
||||||
|
This should be the normal type taken when a function needs a string that will
|
||||||
|
exist until it returns.
|
||||||
|
|
||||||
|
##### CStringView
|
||||||
|
|
||||||
|
```CStringView``` is like ```StringView```, but it comes with the promise that
|
||||||
|
the string ends with a null terminator.
|
||||||
|
Accordingly, it has a ```c_str()``` function in addition to the ```data()```
|
||||||
|
function that ```StringView``` has.
|
||||||
|
|
||||||
|
```CStringView``` should be used when wrapping a C API that only takes C
|
||||||
|
strings.
|
||||||
|
|
||||||
|
##### StringLiteral
|
||||||
|
|
||||||
|
```StringLiteral``` is a string view type, but it kind of straddles the line
|
||||||
|
between view and store types.
|
||||||
|
Creating a ```StringLiteral``` is a promise that you are passing a string
|
||||||
|
literal into the constructor.
|
||||||
|
This means you can treat it like a store, that can be safely used as a copy of
|
||||||
|
the data.
|
||||||
|
Functions that take ```StringLiteral```s are allowed to assume that the data
|
||||||
|
will have no lifetime concerns and hold onto it without any need to make a
|
||||||
|
copy.
|
||||||
|
It has a consteval constructor to enforce the promise that it is a compile time
|
||||||
|
string.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
void f(ox::StringLiteral const&);
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
f("123456789"); // valid
|
||||||
|
f(ox::String{"123456789"}.c_str()); // invalid - will not compile
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Other Variants
|
||||||
|
|
||||||
|
There are a few convenience aliases as well.
|
||||||
|
|
||||||
|
* StringCR = String const&
|
||||||
|
* StringViewCR = StringView const&
|
||||||
|
* CStringViewCR = CStringView const&
|
||||||
|
|
||||||
|
String views do not generally need const references, but it does make debugging
|
||||||
|
easier, as we can skip the constructor call if a string view already exists.
|
||||||
|
|
||||||
|
These kind of aliases probably should not exist for most types, but strings are
|
||||||
|
fundamental and ease of use is desirable.
|
||||||
|
|
||||||
### Logging and Output
|
### Logging and Output
|
||||||
|
|
||||||
Ox provides for logging and debug prints via the ```oxTrace```, ```oxDebug```, and ```oxError``` macros.
|
Ox provides for logging and debug prints via the ```oxTrace```, ```oxDebug```, and ```oxError``` macros.
|
||||||
|
|||||||
Reference in New Issue
Block a user