The custom command that links conflict-set.o depends on
$<TARGET_OBJECTS:conflict-set-object>, but that generator expression
does not create a target-level dependency. With the Unix Makefiles
generator, parallel builds can start building the consuming libraries
before the object library's build rule is available, producing:
gmake[3]: *** No rule to make target
'CMakeFiles/conflict-set-object.dir/ConflictSet.cpp.o', needed by
'conflict-set.o'. Stop.
Add add_dependencies() so that conflict-set and conflict-set-static
cannot build until conflict-set-object has produced its object files.
Closes#47
The user-declared move-assignment operator overwrote `impl` without first
destroying the existing implementation object, leaking all memory and resources
owned by the left-hand side. Self-move-assignment also set `impl` to nullptr,
leaving the object invalid and leaking the old state.
Fix all three implementations (ConflictSet.cpp, SkipList.cpp, HashTable.cpp)
to guard against self-assignment and to destroy/free the old `impl` before
taking ownership of `other.impl`.
ConflictSet_check, ConflictSet_addWrites, ConflictSet_setOldestVersion,
and ConflictSet_destroy return void in C, but the Python wrapper left
their ctypes restype at the default c_int. Set restype = None for each
to match the C API contract and avoid undefined behavior from reading
the return register of void functions.