Apparently MSVC doesn't want typename where it makes sense to use
typename (dependent type from a template). Preprocessor verbosely
saves the day, yet again. Relates #68
cereal no longer permanently modifies the state of internal workings of
std::enable_shared_from_this when saving. cereal *should* be completely
compatible with both saving and loading anything that inherits from this now.
This fixes issue #68 - note that there is still a minor issue regarding
classes declared final that will run into a bug with the way we check for
enable_shared_from_this (see issue #65).
Issue #65 will be addressed in the future by changing the way we check
for derivation from enable_shared_from_this. In the current scheme, we
can detect this even if you use protected inheritance. In the future, cereal
will not be able to get around protected inheritance of enable_shared_from without
befriending cereal::access. This will come at the benefit of allowing classes
declared final to be used with polymorphic serialization.
Previously we took the address of the dereferenced begin() iterator
on a string to get the pointer to its data; we now just const_cast
the pointer that is the result of calling data().
The original reason for using the iterator over something like data()
was to avoid the const_cast and to ensure that any copy on write
mechanisms were used, but this doesn't seem necessary given that we
call resize() immediately prior to this. Valgrind shows no problems
with the new method. Also added unit tests for this case to string.
cereal will now override RAPIDJSON_ASSERT by default to throw a
runtime exception instead of failing an assertion. This can always
be overridden by defining your own RAPIDJSON_ASSERT macro
see #67
Previously if you had an archive that supported eliding empty classes
(such as binary or portable binary), and specialized that archive there would
be an ambiguity in the enable_ifs for serialization.
Addresses concerns in issue #63
Also cleaned up a small amount of leftover commented out code, added const to some things that should be const, and a minor optimization in the JSON search to use strncmp in one instance.
Fixes#47
When we detect a shared_ptr being loaded in load_and_allocate that
also is of a type that derives from enable_shared_from_this, extra
work is done to save the state of the enable_shared_from_this before
the user gets to meddle with it via placement new inside of
cereal::allocate. State is restored after getting back from the user.
Compiles but not stable yet, no interface to use Any within cereal yet. Will be kept internal and not exposed for use
outside of whatever the load/store names will be.
Adding some macros for specialization in case people feel like
typing less scary looking template specialization code.
Modified static assert to remind people that specialization exists.
See issue #25
Moving code around a bit, allocate is now in access.hpp which seems
to make a bit more sense. Exception is now in helpers.hpp.
It is now possible to use a cereal::allocate<T> object to directly
access member variables or functions after it has been initialized.
Accessing them before initialization will throw as will performing
a double initialization.
see #46
Won't have time to finish this one right now, but this solution should work well.
1) Realized there was no reason to do the deferring thing, we just register immediately after
allocation and use that pointer, so got rid of some overhead in code/time on regular shared_ptr loads.
2) For cases with no default constructor the interface will be changing slightly. Instead of having the
user do both the allocation and initialization, the user will only be responsible for the initialization.
This works as follows:
We allocate std::aligned_storage big enough for the type and pack it into a shared_ptr for the proper type with
a custom deleter to correctly call the proper destructors. We'll wrap up this raw pointer in a new class called
cereal::allocation (or similar) which will now be passed along with the archive as a reference to the load and
allocate function. The user now loads up their data as before using the archive, and then instead of performing
a raw call to operator new, they pass all of their arguments to the operator() of the cereal::allocation object
which then performs a placement new into the aligned_storage (transparent to the user). Should resolve the circular
reference problem too.
to handle circular nested shared pointer references, we split registration
for an id into a pre and post portion, where pre marks it as being dirty and
post marks it clean (valid). if we are loading up a reference to something that is
in the progress of being loaded (a nested case), we defer our load until it is no longer
dirty and perform the load afer the post condition happens.
load_and_allocate did not properly enter into the 'data' NVP that the
ptr_wrapper creates for unique/shared ptr. When loading these types,
we now go through a wrapper struct to force entry into an extra node to
resolve this issue.
Changes to unittests are for an issue compiling with g++-4.7.3 under
Ubuntu where steady_clock::now() is not defined for some reason