From d003eceb72357a9c7ba0acb9fbb227de1f56b125 Mon Sep 17 00:00:00 2001 From: ljfa-ag Date: Sat, 18 Jul 2015 23:50:08 +0200 Subject: Elaborate on use and rationale of value and value_initializer --- include/value.h | 30 ++++++++++++++++++++++++++++-- include/value_initializer.h | 15 +++++++++++++-- 2 files changed, 41 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/value.h b/include/value.h index 2dc4e10207..670fc3fe8e 100644 --- a/include/value.h +++ b/include/value.h @@ -30,8 +30,34 @@ namespace nbt /** * @brief Contains an NBT value of fixed type * - * A convenience wrapper around @c std::unique_ptr, contains a tag of - * fixed type. + * This class is a convenience wrapper for @c std::unique_ptr. + * A value can contain any kind of tag or no tag (nullptr) and provides + * operations for handling tags of which the type is not known at compile time. + * Assignment or the set method on a value with no tag will fill in the value. + * Once the value contains a tag, the type of the contained tag will not change + * unless set_ptr is used. + * + * The rationale for the existance of this class is to provide a type-erasured + * means of storing tags, especially when they are contained in tag_compound + * or tag_list. The alternative would be directly using @c std::unique_ptr + * and @c tag&, which is how it was done in libnbt++1. The main drawback is that + * it becomes very cumbersome to deal with tags of unknown type. + * + * For example, in this case it would not be possible to allow a syntax like + * compound["foo"] = 42. If the key "foo" does not exist beforehand, + * the left hand side could not have any sensible value if it was of type + * @c tag&. + * Firstly, the compound tag would have to create a new tag_int there, but it + * cannot know that the new tag is going to be assigned an integer. + * Also, if the type was @c tag& and it allowed assignment of integers, that + * would mean the tag base class has assignments and conversions like this. + * Which means that all other tag classes would inherit them from the base + * class, even though it does not make any sense to allow converting a + * tag_compound into an integer. Attempts like this should be caught at + * compile time. + * + * This is why all the syntactic sugar for tags is contained in the value class + * while the tag class only contains common operations for all tag types. */ class value { diff --git a/include/value_initializer.h b/include/value_initializer.h index f50527546d..4ba07cb8c1 100644 --- a/include/value_initializer.h +++ b/include/value_initializer.h @@ -27,8 +27,19 @@ namespace nbt /** * @brief Helper class for implicitly constructing value objects - * @note Instances of this class can unproblematically be "sliced" (converted) - * into @ref value objects. + * + * This type is a subclass of @ref value. However the only difference to value + * is that this class has additional constructors which allow implicit + * conversion of various types to value objects. These constructors are not + * part of the value class itself because implicit conversions like this + * (especially from @c tag&& to @c value) can cause problems and ambiguities + * in some cases. + * + * value_initializer is especially useful as function parameter type, it will + * allow convenient conversion of various values to tags on function call. + * + * As value_initializer objects are in no way different than value objects, + * they can just be converted to value after construction. */ class value_initializer : public value { -- cgit 0.0.5-2-1-g0f52