You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2019/01/04 12:26:51 UTC
svn commit: r1850355 - in /subversion/trunk/subversion/bindings/cxx:
include/svnxx/revision.hpp tests/test_revision.cpp
Author: brane
Date: Fri Jan 4 12:26:51 2019
New Revision: 1850355
URL: http://svn.apache.org/viewvc?rev=1850355&view=rev
Log:
Make the revision kind in SVN++ svn::revision explicitly immutable.
It's illogical to be able to even theoretically change the kind of a revision
object, so we make that restriction explicit by making the class member const.
[in subversion/bindings/cxx]
* include/svnxx/revision.hpp: Include <new> for placement-new.
(revision::tag): Make this immutable.
(revision::operator=): New; work around the kind tag's immutability by
destroying the object and creating a new object in place.
* tests/test_revision.cpp
(assignment): New test case.
Modified:
subversion/trunk/subversion/bindings/cxx/include/svnxx/revision.hpp
subversion/trunk/subversion/bindings/cxx/tests/test_revision.cpp
Modified: subversion/trunk/subversion/bindings/cxx/include/svnxx/revision.hpp
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/cxx/include/svnxx/revision.hpp?rev=1850355&r1=1850354&r2=1850355&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/cxx/include/svnxx/revision.hpp (original)
+++ subversion/trunk/subversion/bindings/cxx/include/svnxx/revision.hpp Fri Jan 4 12:26:51 2019
@@ -30,6 +30,7 @@
#include <chrono>
#include <cstdint>
+#include <new>
#include "tristate.hpp"
@@ -126,6 +127,18 @@ public:
{}
/**
+ * @brief Assignment operator.
+ * Uses in-place destruction/construction to maintain the immutability
+ * of the revision kind.
+ */
+ revision& operator=(const revision& that)
+ {
+ this->~revision();
+ new(this) revision(that);
+ return *this;
+ }
+
+ /**
* @brief Return the revision kind.
*/
kind get_kind() const noexcept
@@ -161,7 +174,7 @@ public:
private:
// Even if we were using C++17, we wouldn't use std::variant because we
// already maintain an explicit discriminator tag for the union.
- kind tag; // Union discriminator
+ const kind tag; // Union discriminator
union {
number revnum; // (tag == kind::number): revision number.
time<usec> date; // (tag == kind::date): microseconds from epoch.
Modified: subversion/trunk/subversion/bindings/cxx/tests/test_revision.cpp
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/cxx/tests/test_revision.cpp?rev=1850355&r1=1850354&r2=1850355&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/cxx/tests/test_revision.cpp (original)
+++ subversion/trunk/subversion/bindings/cxx/tests/test_revision.cpp Fri Jan 4 12:26:51 2019
@@ -130,6 +130,28 @@ BOOST_AUTO_TEST_CASE(postconditions_date
BOOST_CHECK_THROW(r.get_number(), std::logic_error);
}
+BOOST_AUTO_TEST_CASE(assignment)
+{
+ using kind = svn::revision::kind;
+ using clock = std::chrono::system_clock;
+ const auto timestamp = clock::now();
+
+ svn::revision r;
+ BOOST_TEST((r.get_kind() == kind::unspecified));
+
+ r = svn::revision(kind::previous);
+ BOOST_TEST((r.get_kind() == kind::previous));
+
+ r = svn::revision(svn::revnum(0));
+ BOOST_TEST((r.get_kind() == kind::number));
+ BOOST_TEST((r.get_number() == svn::revnum(0)));
+
+ r = svn::revision(timestamp);
+ BOOST_TEST((r.get_kind() == kind::date));
+ BOOST_TEST((r.get_date<clock::duration>() == timestamp));
+ BOOST_TEST((r.get_date<svn::revision::usec>() == timestamp));
+}
+
// TODO: Add tests for !=, <, >, <= and >=
BOOST_AUTO_TEST_SUITE_END();