Author: mordante
Date: Sat Oct 4 23:42:20 2008
New Revision: 29884
URL: http://svn.gna.org/viewcvs/wesnoth?rev=29884&view=rev
Log:
Add a copy policy templates.
These will be used for the font::ttext class, for now the class needs move
semantics but that might change later. This change will be committed later.
Also added the unit tests for the policies.
Added:
trunk/src/copy_policy.hpp (with props)
trunk/src/tests/test_policy.cpp (with props)
Modified:
trunk/src/CMakeLists.txt
trunk/src/Makefile.am
trunk/src/SConscript
Modified: trunk/src/CMakeLists.txt
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/CMakeLists.txt?rev=29884&r1=29883&r2=29884&view=diff
==============================================================================
--- trunk/src/CMakeLists.txt (original)
+++ trunk/src/CMakeLists.txt Sat Oct 4 23:42:20 2008
@@ -456,6 +456,7 @@
tests/test_config_cache.cpp
tests/test_formula_ai.cpp
tests/test_network_worker.cpp
+ tests/test_policy.cpp
tests/test_team.cpp
tests/test_util.cpp
tests/gui/test_save_dialog.cpp
Modified: trunk/src/Makefile.am
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/Makefile.am?rev=29884&r1=29883&r2=29884&view=diff
==============================================================================
--- trunk/src/Makefile.am (original)
+++ trunk/src/Makefile.am Sat Oct 4 23:42:20 2008
@@ -272,6 +272,7 @@
tests/test_config_cache.cpp \
tests/test_formula_ai.cpp \
tests/test_network_worker.cpp \
+ tests/test_policy.cpp \
tests/test_team.cpp \
tests/test_util.cpp \
tests/gui/test_save_dialog.cpp \
Modified: trunk/src/SConscript
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/SConscript?rev=29884&r1=29883&r2=29884&view=diff
==============================================================================
--- trunk/src/SConscript (original)
+++ trunk/src/SConscript Sat Oct 4 23:42:20 2008
@@ -354,6 +354,7 @@
tests/main.cpp
tests/test_formula_ai.cpp
tests/test_network_worker.cpp
+ tests/test_policy.cpp
tests/test_team.cpp
tests/test_util.cpp
tests/gui/test_drop_target.cpp
Added: trunk/src/copy_policy.hpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/copy_policy.hpp?rev=29884&view=auto
==============================================================================
--- trunk/src/copy_policy.hpp (added)
+++ trunk/src/copy_policy.hpp Sat Oct 4 23:42:20 2008
@@ -1,0 +1,156 @@
+/* $Id$ */
+/*
+ Copyright (C) 2008 by Mark de Wever <[EMAIL PROTECTED]>
+ Part of the Battle for Wesnoth Project http://www.wesnoth.org/
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License version 2
+ or at your option any later version.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY.
+
+ See the COPYING file for more details.
+*/
+
+/**
+ * @file copy_policies.hpp.
+ * Defines the copy policies for classes.
+ *
+ * When a class can have multiple copy policies these templates can be used.
+ * When a class uses this class it should define its own copy constructor to do
+ * a shallow copy and call copy() afterwards. Also it should define a
assignment
+ * operator which does a shallow copy and then call copy() (copy() test for
self
+ * assignment, but the assignment operator can also do the test.
+ *
+ * See tests/test_policy.cpp for an example implementation of this policy.
+ */
+
+#ifndef COPY_POLICY_HPP_INCLUDED
+#define COPY_POLICY_HPP_INCLUDED
+
+#include <boost/static_assert.hpp>
+
+/** Set to 1 if you want debug output to std::cerr. */
+#define COPY_POLICY_DEBUG 0
+
+#if COPY_POLICY_DEBUG
+#include <iostream>
+#endif
+
+/** Contains various policies for policy based designs. */
+namespace policies {
+
+/** Utilities for the policies. */
+namespace utils {
+
+/** Gets the reference version of type T. */
+template <class T>
+class treference_type
+{
+ template<class U>
+ struct thelper
+ {
+ typedef U& type;
+ };
+ template<class U>
+ struct thelper<U&>
+ {
+ typedef U type;
+ };
+public:
+ typedef typename thelper<T>::type type;
+};
+
+} // namespace utils
+
+/**
+ * Allow no copies.
+ *
+ * When a class never should be copyable boost::noncopyable is a better
+ * alternative (or just do it manually).
+ */
+template<class T>
+class tno_copy
+{
+public:
+ /** The type to use in the copy constructor and assignment operator. */
+ typedef const typename utils::treference_type<T>::type rhs_type;
+
+ void copy(rhs_type /*rhs*/)
+ {
+ BOOST_STATIC_ASSERT(sizeof(T) == 0);
+ }
+};
+
+/**
+ * Makes a shallow copy.
+ *
+ * Since the subclass already does the shallow part we do nothing.
+ */
+template<class T>
+class tshallow_copy
+{
+public:
+ /** The type to use in the copy constructor and assignment operator. */
+ typedef const typename utils::treference_type<T>::type rhs_type;
+
+ void copy(rhs_type /*rhs*/)
+ {
+#if COPY_POLICY_DEBUG
+ std::cerr << __func__ << ".\n";
+#endif
+ }
+};
+
+/**
+ * Makes a deep copy.
+ *
+ * The subclass must define a function void clone() which gets called to do
+ * the copying.
+ */
+template<class T>
+class tdeep_copy
+{
+public:
+ /** The type to use in the copy constructor and assignment operator. */
+ typedef const typename utils::treference_type<T>::type rhs_type;
+
+ void copy(rhs_type rhs)
+ {
+#if COPY_POLICY_DEBUG
+ std::cerr << __func__ << ".\n";
+#endif
+ if(&rhs != this) {
+ static_cast<typename
utils::treference_type<T>::type>(*this).clone();
+ }
+ }
+};
+
+/**
+ * Makes a move copy.
+ *
+ * The shared resources are moved from the original class to the copy and
+ * thus the original object no longer owns them. The subclass must define a
+ * function void dispose() which should clear the resources.
+ */
+template<class T>
+class tmove_copy
+{
+public:
+ /** The type to use in the copy constructor and assignment operator. */
+ typedef typename utils::treference_type<T>::type rhs_type;
+
+ void copy(rhs_type rhs)
+ {
+#if COPY_POLICY_DEBUG
+ std::cerr << __func__ << ".\n";
+#endif
+ if(&rhs != this) {
+ rhs.invalidate();
+ }
+ }
+};
+
+} // namespace policy
+
+#endif
Propchange: trunk/src/copy_policy.hpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: trunk/src/copy_policy.hpp
------------------------------------------------------------------------------
svn:keywords = 'Author Date Id Revision'
Added: trunk/src/tests/test_policy.cpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/tests/test_policy.cpp?rev=29884&view=auto
==============================================================================
--- trunk/src/tests/test_policy.cpp (added)
+++ trunk/src/tests/test_policy.cpp Sat Oct 4 23:42:20 2008
@@ -1,0 +1,226 @@
+/* $Id$ */
+/*
+ Copyright (C) 2008 by Mark de Wever <[EMAIL PROTECTED]>
+ Part of the Battle for Wesnoth Project http://www.wesnoth.org/
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License version 2
+ or at your option any later version.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY.
+
+ See the COPYING file for more details.
+*/
+
+#include "utils/test_support.hpp"
+
+#include "copy_policy.hpp"
+
+/** Set to 1 if you want debug output to std::cerr. */
+#define TEST_POLICY_DEBUG 0
+
+#if TEST_POLICY_DEBUG
+#include <iostream>
+#endif
+
+BOOST_AUTO_TEST_SUITE( policy )
+
+namespace {
+
+/** Class to test the copy policies. */
+template <template<class> class copy_policy >
+struct ttest : public copy_policy<ttest<copy_policy> >
+{
+ typedef copy_policy<ttest<copy_policy> > policy;
+ typedef typename ttest<copy_policy>::rhs_type rhs_type;
+
+ ttest()
+ : policy()
+ , copied_constructed_(false)
+ , assigned_(false)
+ , cloned_(false)
+ , invalidated_(false)
+ {
+#if TEST_POLICY_DEBUG
+ std::cerr << "Default constructor " << __func__ << ".\n";
+#endif
+ }
+
+ ttest(rhs_type rhs)
+ : policy(rhs)
+ , copied_constructed_(true)
+ , assigned_(rhs.assigned_)
+ , cloned_(rhs.cloned_)
+ , invalidated_(rhs.invalidated_)
+ {
+#if TEST_POLICY_DEBUG
+ std::cerr << "Copy constructor " << __func__ << ".\n";
+#endif
+ copy(rhs);
+ }
+
+ ttest& operator=(rhs_type rhs)
+ {
+#if TEST_POLICY_DEBUG
+ std::cerr << __func__ << ".\n";
+#endif
+ copied_constructed_ = rhs.copied_constructed_;
+ assigned_ = true;
+ cloned_ = rhs.cloned_;
+ invalidated_ = rhs.invalidated_;
+
+ copy(rhs);
+
+ return *this;
+ }
+
+ /** Mandatory helper for the tmove_copy policy. */
+ void invalidate() { invalidated_ = true; }
+
+ /** Mandatory helper for the tdeep_copy policy. */
+ void clone() { cloned_ = true; }
+
+ /** A group helper variables */
+ bool copied_constructed_
+ , assigned_
+ , cloned_
+ , invalidated_
+ ;
+};
+
+// Not really required but doesn't hurt.
+#if TEST_POLICY_DEBUG
+template<template<class >class T>
+std::ostream& operator<<(std::ostream &s, const ttest<T>& test)
+{
+ s << "copied_constructed_ " << test.copied_constructed_
+ << " assigned_ " << test.assigned_
+ << " cloned_ " << test.cloned_
+ << " invalidated_ " << test.invalidated_
+ ;
+
+ return s;
+}
+#endif
+
+/** Tests the copy constructor of the policy. */
+template<template<class >class T>
+void copy_test(const bool orig_invalidated, const bool copy_cloned)
+{
+#if TEST_POLICY_DEBUG
+ std::cerr << __func__ << ".\n";
+#endif
+
+ ttest<T> orig;
+ ttest<T> cpy(orig);
+
+#if TEST_POLICY_DEBUG
+ std::cerr << "orig " << orig
+ << "\ncopy " << cpy
+ << ".\n";
+#endif
+
+ BOOST_REQUIRE_EQUAL(orig.copied_constructed_, false);
+ BOOST_REQUIRE_EQUAL(orig.assigned_, false);
+ BOOST_REQUIRE_EQUAL(orig.cloned_, false);
+ BOOST_REQUIRE_EQUAL(orig.invalidated_, orig_invalidated);
+
+ BOOST_REQUIRE_EQUAL(cpy.copied_constructed_, true);
+ BOOST_REQUIRE_EQUAL(cpy.assigned_, false);
+ BOOST_REQUIRE_EQUAL(cpy.cloned_, copy_cloned);
+ BOOST_REQUIRE_EQUAL(cpy.invalidated_, false);
+}
+
+/** Tests the assignment operator of the policy. */
+template<template<class >class T>
+void assign_test(const bool orig_invalidated, const bool copy_cloned)
+{
+#if TEST_POLICY_DEBUG
+ std::cerr << __func__ << ".\n";
+#endif
+ ttest<T> orig;
+ ttest<T> cpy;
+
+ cpy = orig;
+
+#if TEST_POLICY_DEBUG
+ std::cerr << "orig " << orig
+ << "\ncopy " << cpy
+ << ".\n";
+#endif
+
+ BOOST_REQUIRE_EQUAL(orig.copied_constructed_, false);
+ BOOST_REQUIRE_EQUAL(orig.assigned_, false);
+ BOOST_REQUIRE_EQUAL(orig.cloned_, false);
+ BOOST_REQUIRE_EQUAL(orig.invalidated_, orig_invalidated);
+
+ BOOST_REQUIRE_EQUAL(cpy.copied_constructed_, false);
+ BOOST_REQUIRE_EQUAL(cpy.assigned_, true);
+ BOOST_REQUIRE_EQUAL(cpy.cloned_, copy_cloned);
+ BOOST_REQUIRE_EQUAL(cpy.invalidated_, false);
+}
+
+/**
+ * Tests a policy.
+ *
+ * @param orig_invalidated Should the original object be invalidated
when
+ * used as rhs in an assignment or as parameter
+ * in a copy constructor.
+ * @param copy_cloned Should the copy be cloned when use as lhs in
+ * an assignment or when being copy constructed.
+ */
+template<template<class >class T>
+void test(const bool orig_invalidated, const bool copy_cloned)
+{
+ copy_test<T>(orig_invalidated, copy_cloned);
+ assign_test<T>(orig_invalidated, copy_cloned);
+}
+
+} // namespace
+
+BOOST_AUTO_TEST_CASE( test_copy_policy )
+{
+/*
+ * The no copy policy shouldn't compile so it's commented out. The first part
+ * enables the basics and can also test whether the compiler does a RVO [1],
+ * if the compiler does the copy1 can be constructed. The second part should
+ * always fail.
+ *
+ * [1] http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.9
+ */
+#if 0
+ ttest<policies::tno_copy> orig;
+
+ // Might or might not compile.
+ ttest<policies::tno_copy> copy1(ttest<policies::tno_copy>());
+#if 0
+ // Must fail to compile.
+ ttest<policies::tno_copy> copy2(orig);
+
+ // Must fail to compile.
+ orig = orig;
+#endif
+#endif
+
+#if TEST_POLICY_DEBUG
+ std::cerr << std::boolalpha;
+#endif
+
+#if TEST_POLICY_DEBUG
+ std::cerr << "Test shallow copy\n";
+#endif
+ test<policies::tshallow_copy>(false, false);
+
+#if TEST_POLICY_DEBUG
+ std::cerr << "\n\nTest deep copy\n";
+#endif
+ test<policies::tdeep_copy>(false, true);
+
+#if TEST_POLICY_DEBUG
+ std::cerr << "\n\nTest move copy\n";
+#endif
+ test<policies::tmove_copy>(true, false);
+}
+
+/* vim: set ts=4 sw=4: */
+BOOST_AUTO_TEST_SUITE_END()
Propchange: trunk/src/tests/test_policy.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: trunk/src/tests/test_policy.cpp
------------------------------------------------------------------------------
svn:keywords = 'Author Date Id Revision'
_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits