I have many concrete-structs and I want to designate fields as optional (present or not-present). Just wondering what ideas people have for achieving this. Here is an example struct (fields can be other structs as well, even vectors of structs):
struct LogonMessage_t
{
Header_t header; // this points to another struct containing all primitives
std::string username;
std::string password;
std::vector<LogonOption_t> LogonOptions;
int subaccountid;
std::string Text;
}
I'd like to default all fields to not-present and enable them one by one, perhaps in their setters. Since these structs are generated, a generic method would be preferable.
My ideas so far are:
- Bitmap of fields indicating if a field is set or not
- Use sentinel values ("\0" for std::string, -1 for int, -1.0f for float
- Some kind of template container/proxy encapsulating each field to indicate if it's set or not, any ideas? I think this might be the best approach.
Btw, using maps or other STL containers to encapsulate the fields won't work here, they need to be concrete structs.
Keep it simple. Use a flag member variable that you can set by or-ing constants together and inspect by and-ing them.
Problem with sentinel values is choosing ones that are not also legal field values (now and in the future).
Both string and vector has an empty default state, which you can test for with
if (username.empty())
etc.For a
subaccountid
I would guess that 0 would be a similar empty value. Otherwise -1 could be ok.Sounds like you want boost.optional.
I'd use one a flag. I can propose you two method, one keeping the value on the heap and one on the stack.
In the first you use a std::pair and the first field is the existence-flag. The second approach is via a boost::shard_ptr, if pointer points to 0 the field is not existing.
In both the cases my advice is not to access directly to the element in Value but using instead a couple of functions. const Value& value() const { return } Value& value() { return }
francesco