QEverCloud
Unofficial Evernote Cloud API for Qt
|
Supports optional values. More...
Public Member Functions | |
Optional () | |
Default constructor. More... | |
Optional (const Optional &o) | |
Copy constructor. | |
template<typename X > | |
Optional (const Optional< X > &o) | |
Template copy constructor. More... | |
Optional (const T &value) | |
Initialization with a value of the type T. More... | |
template<typename X > | |
Optional (const X &value) | |
Template initialization with a value of any compatible type. | |
void | clear () |
Clears an Optional. More... | |
Optional & | init () |
Fast way to initialize an Optional with a default value. More... | |
bool | isEqual (const Optional< T > &other) const |
Two optionals are equal if they are both not set or have equal values. More... | |
bool | isSet () const |
Checks if value is set. More... | |
operator const T & () const | |
Implicit conversion of Optional<T> to T. More... | |
operator T & () | |
Implicit conversion of Optional<T> to T. More... | |
T * | operator-> () |
Two syntatic constructs come to mind to use for implementation of access to a struct's/class's field directly from Optional. More... | |
const T * | operator-> () const |
const version. | |
Optional & | operator= (const Optional &o) |
Assignment. | |
template<typename X > | |
Optional & | operator= (const Optional< X > &o) |
Template assignment with an Optional of any compatible value. | |
Optional & | operator= (const T &value) |
Assignment with a value of the type T. | |
template<typename X > | |
Optional & | operator= (const X &value) |
Template assignment with a value of any compatible type. | |
const T & | ref () const |
Returs a reference to the holded value. More... | |
T & | ref () |
Returs reference to the holded value. More... | |
T | value (T defaultValue=T()) const |
The function is sometimes useful to simplify checking for the value being set. More... | |
Friends | |
void | swap (Optional &first, Optional &second) |
Supports optional values.
Most of the fields in the Evernote API structs are optional. But ะก++ does not support this notion directly.
To implement the concept of optional values conventional Thrift C++ wrapper uses a special field of a struct type where each field is of type bool with the same name as a field in the struct. This bool flag indicated was the field with the same name in the outer struct assigned or not.
While this method have its advantages (obviousness and simplicity) I found it very inconvenient to work with. You have to check by hand that both values (value itself and its __isset flag) are in sync. There is no checks whatsoever against an error and such an error is too easy to make.
So for my library I created a special class that supports the optional value notion explicitly. Basically Optional class just holds a bool value that tracks the fact that a value was assigned. But this tracking is done automatically and attempts to use unissigned values throw exceptions. In this way errors are much harder to make and it's harder for them to slip through testing unnoticed too.
|
inline |
Default constructor.
Default Optional is not set.
|
inline |
Template copy constructor.
Allows to be initialized with Optional of any compatible type.
|
inline |
Initialization with a value of the type T.
Note: it's implicit.
|
inline |
Clears an Optional.
|
inline |
Fast way to initialize an Optional with a default value.
It's very useful for structs.
|
inline |
Two optionals are equal if they are both not set or have equal values.
I do not define operator==
due to not easily resolvable conflicts with operator T&
.
Note that optional == other_optional
may throw but optional.isEqual(other_optional)
will not.
|
inline |
|
inline |
Implicit conversion of Optional<T> to T.
const version.
|
inline |
Implicit conversion of Optional<T> to T.
Note: a reference is returned, not a copy.
|
inline |
Two syntatic constructs come to mind to use for implementation of access to a struct's/class's field directly from Optional.
One is the dereference operator. This is what boost::optional uses. While it's conceptually nice I found it to be not a very convenient way to refer to structs, especially nested ones. So I overloaded the operator-> and use smart pointer semantics.
I admit, boost::optional is much more elegant overall. It uses pointer semantics quite clearly and in an instantly understandable way. It's universal (* works for any type and not just structs). There is no need for implicit type concersions and so there is no subtleties because of it. And so on.
But then referring to struct fields is a chore. And this is the most common use case of Optionals in QEverCloud.
So I decided to use non-obvious-on-the-first-sight semantics for my Optional. IMO it's much more convenient when gotten used to.
|
inline |
Returs a reference to the holded value.
const version.
|
inline |
Returs reference to the holded value.
There are contexts in C++ where impicit type conversions can't help. For example:
Explicit type conversion can be used...
... but this is indeed ugly as hell.
So I implemented ref() function that returns a reference to the holded value.
|
inline |