aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar David Leverton <levertond@googlemail.com> 2007-05-27 19:56:44 +0000
committerAvatar David Leverton <levertond@googlemail.com> 2007-05-27 19:56:44 +0000
commit300159bf1d9bd3a588718190393e275cdd290530 (patch)
treed84524d1159f885231bf0003dd4617f61bb3bacf
parente5d1a4d5809f38fc99ee3c5e13aa496df160019b (diff)
downloadpaludis-300159bf1d9bd3a588718190393e275cdd290530.tar.gz
paludis-300159bf1d9bd3a588718190393e275cdd290530.tar.xz
Add DepSpec->clone(). Fixes: ticket:255
-rw-r--r--paludis/dep_spec.cc41
-rw-r--r--paludis/dep_spec.hh20
-rw-r--r--paludis/dep_spec_TEST.cc26
-rw-r--r--paludis/util/clone-impl.hh44
-rw-r--r--paludis/util/clone.hh87
-rw-r--r--paludis/util/files.m41
6 files changed, 216 insertions, 3 deletions
diff --git a/paludis/dep_spec.cc b/paludis/dep_spec.cc
index 36fc18e..18cf74a 100644
--- a/paludis/dep_spec.cc
+++ b/paludis/dep_spec.cc
@@ -18,6 +18,7 @@
*/
#include <paludis/dep_spec.hh>
+#include <paludis/util/clone-impl.hh>
#include <paludis/util/log.hh>
#include <paludis/util/collection_concrete.hh>
#include <paludis/util/iterator.hh>
@@ -157,10 +158,22 @@ AnyDepSpec::AnyDepSpec()
{
}
+tr1::shared_ptr<DepSpec>
+AnyDepSpec::clone() const
+{
+ return tr1::shared_ptr<AnyDepSpec>(new AnyDepSpec());
+}
+
AllDepSpec::AllDepSpec()
{
}
+tr1::shared_ptr<DepSpec>
+AllDepSpec::clone() const
+{
+ return tr1::shared_ptr<AllDepSpec>(new AllDepSpec());
+}
+
UseDepSpec::UseDepSpec(const UseFlagName & our_flag, bool is_inverse) :
_flag(our_flag),
_inverse(is_inverse)
@@ -185,6 +198,12 @@ UseDepSpec::inverse() const
return _inverse;
}
+tr1::shared_ptr<DepSpec>
+UseDepSpec::clone() const
+{
+ return tr1::shared_ptr<UseDepSpec>(new UseDepSpec(_flag, _inverse));
+}
+
std::string
StringDepSpec::text() const
{
@@ -219,6 +238,7 @@ PackageDepSpec::PackageDepSpec(const QualifiedPackageName & our_package) :
}
PackageDepSpec::PackageDepSpec(const PackageDepSpec & other) :
+ Cloneable<DepSpec>(),
StringDepSpec(stringify(other)),
PrivateImplementationPattern<PackageDepSpec>(new Implementation<PackageDepSpec>(
other._imp->package_ptr,
@@ -750,6 +770,12 @@ PlainTextDepSpec::PlainTextDepSpec(const std::string & s) :
{
}
+tr1::shared_ptr<DepSpec>
+PlainTextDepSpec::clone() const
+{
+ return tr1::shared_ptr<DepSpec>(new PlainTextDepSpec(text()));
+}
+
namespace paludis
{
/**
@@ -821,6 +847,15 @@ PackageDepSpec::without_use_requirements() const
return result;
}
+tr1::shared_ptr<DepSpec>
+PackageDepSpec::clone() const
+{
+ tr1::shared_ptr<PackageDepSpec> result(new PackageDepSpec(*this));
+ result->_make_unique();
+ result->set_tag(_imp->tag);
+ return result;
+}
+
tr1::shared_ptr<const QualifiedPackageName>
PackageDepSpec::package_ptr() const
{
@@ -934,3 +969,9 @@ BlockDepSpec::blocked_spec() const
return _spec;
}
+tr1::shared_ptr<DepSpec>
+BlockDepSpec::clone() const
+{
+ return tr1::shared_ptr<DepSpec>(new BlockDepSpec(tr1::static_pointer_cast<PackageDepSpec>(_spec->clone())));
+}
+
diff --git a/paludis/dep_spec.hh b/paludis/dep_spec.hh
index d506f0c..18b38d5 100644
--- a/paludis/dep_spec.hh
+++ b/paludis/dep_spec.hh
@@ -17,13 +17,14 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef PALUDIS_GUARD_PALUDIS_DEP_ATOM_HH
-#define PALUDIS_GUARD_PALUDIS_DEP_ATOM_HH 1
+#ifndef PALUDIS_GUARD_PALUDIS_DEP_SPEC_HH
+#define PALUDIS_GUARD_PALUDIS_DEP_SPEC_HH 1
#include <paludis/dep_spec-fwd.hh>
#include <paludis/dep_tag.hh>
#include <paludis/name.hh>
#include <paludis/util/attributes.hh>
+#include <paludis/util/clone.hh>
#include <paludis/util/instantiation_policy.hh>
#include <paludis/util/visitor.hh>
#include <paludis/version_requirements.hh>
@@ -49,7 +50,8 @@ namespace paludis
* \nosubgrouping
*/
class PALUDIS_VISIBLE DepSpec :
- private InstantiationPolicy<DepSpec, instantiation_method::NonCopyableTag>
+ private InstantiationPolicy<DepSpec, instantiation_method::NonCopyableTag>,
+ public virtual Cloneable<DepSpec>
{
protected:
DepSpec();
@@ -98,6 +100,8 @@ namespace paludis
AnyDepSpec();
///\}
+
+ virtual tr1::shared_ptr<DepSpec> clone() const PALUDIS_ATTRIBUTE((warn_unused_result));
};
/**
@@ -117,6 +121,8 @@ namespace paludis
AllDepSpec();
///\}
+
+ virtual tr1::shared_ptr<DepSpec> clone() const PALUDIS_ATTRIBUTE((warn_unused_result));
};
/**
@@ -151,6 +157,8 @@ namespace paludis
bool inverse() const;
virtual const UseDepSpec * as_use_dep_spec() const;
+
+ virtual tr1::shared_ptr<DepSpec> clone() const PALUDIS_ATTRIBUTE((warn_unused_result));
};
/**
@@ -352,6 +360,8 @@ namespace paludis
tr1::shared_ptr<PackageDepSpec> without_use_requirements() const;
virtual const PackageDepSpec * as_package_dep_spec() const;
+
+ virtual tr1::shared_ptr<DepSpec> clone() const PALUDIS_ATTRIBUTE((warn_unused_result));
};
/**
@@ -371,6 +381,8 @@ namespace paludis
PlainTextDepSpec(const std::string &);
///\}
+
+ virtual tr1::shared_ptr<DepSpec> clone() const PALUDIS_ATTRIBUTE((warn_unused_result));
};
/**
@@ -418,6 +430,8 @@ namespace paludis
* Fetch the spec we're blocking.
*/
tr1::shared_ptr<const PackageDepSpec> blocked_spec() const;
+
+ virtual tr1::shared_ptr<DepSpec> clone() const PALUDIS_ATTRIBUTE((warn_unused_result));
};
}
diff --git a/paludis/dep_spec_TEST.cc b/paludis/dep_spec_TEST.cc
index 5fac48f..9059a38 100644
--- a/paludis/dep_spec_TEST.cc
+++ b/paludis/dep_spec_TEST.cc
@@ -235,5 +235,31 @@ namespace test_cases
TEST_CHECK(! f.category_name_part_ptr());
}
} test_package_dep_spec_unspecific;
+
+ struct DepSpecCloneTest : TestCase
+ {
+ DepSpecCloneTest() : TestCase("dep spec clone") { }
+
+ void run()
+ {
+ PackageDepSpec a("cat/pkg:1::repo[=1|>3.2][foo]", pds_pm_permissive);
+
+ tr1::shared_ptr<PackageDepSpec> b(tr1::static_pointer_cast<PackageDepSpec>(a.clone()));
+ TEST_CHECK_STRINGIFY_EQUAL(a, *b);
+ b->set_version_requirements_mode(vr_and);
+ TEST_CHECK(stringify(a) != stringify(*b));
+
+ tr1::shared_ptr<PackageDepSpec> c(tr1::static_pointer_cast<PackageDepSpec>(a.clone()));
+ TEST_CHECK_STRINGIFY_EQUAL(a, *c);
+ c->version_requirements_ptr()->append(VersionRequirement(vo_tilde, VersionSpec("1.5")));
+ TEST_CHECK(stringify(a) != stringify(*c));
+
+ BlockDepSpec d(c);
+ tr1::shared_ptr<BlockDepSpec> e(tr1::static_pointer_cast<BlockDepSpec>(d.clone()));
+ TEST_CHECK_STRINGIFY_EQUAL(*(d.blocked_spec()), *(e->blocked_spec()));
+ c->set_version_requirements_mode(vr_and);
+ TEST_CHECK(stringify(*(d.blocked_spec())) != stringify(*(e->blocked_spec())));
+ }
+ } test_dep_spec_clone;
}
diff --git a/paludis/util/clone-impl.hh b/paludis/util/clone-impl.hh
new file mode 100644
index 0000000..14efe93
--- /dev/null
+++ b/paludis/util/clone-impl.hh
@@ -0,0 +1,44 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 David Leverton <u01drl3@abdn.ac.uk>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_UTIL_CLONE_IMPL_HH
+#define PALUDIS_GUARD_PALUDIS_UTIL_CLONE_IMPL_HH 1
+
+namespace paludis
+{
+ template<typename T_>
+ Cloneable<T_>::~Cloneable()
+ {
+ }
+
+ template<typename Base_, typename Child_>
+ tr1::shared_ptr<Base_>
+ CloneUsingThis<Base_, Child_>::clone() const
+ {
+ return tr1::shared_ptr<Base_>(new Child_(*static_cast<const Child_ *>(this)));
+ }
+
+ template<typename Base_, typename Child_>
+ CloneUsingThis<Base_, Child_>::~CloneUsingThis()
+ {
+ }
+}
+
+#endif
+
diff --git a/paludis/util/clone.hh b/paludis/util/clone.hh
new file mode 100644
index 0000000..be08d0e
--- /dev/null
+++ b/paludis/util/clone.hh
@@ -0,0 +1,87 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 David Leverton <u01drl3@abdn.ac.uk>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_UTIL_CLONE_HH
+#define PALUDIS_GUARD_PALUDIS_UTIL_CLONE_HH 1
+
+#include <paludis/util/attributes.hh>
+#include <paludis/util/tr1_memory.hh>
+
+/** \file
+ * Declares the Cloneable class and helpers.
+ *
+ * \ingroup grpclone
+ */
+
+namespace paludis
+{
+ /**
+ * Base class for objects that can be cloned.
+ *
+ * \ingroup grpclone
+ * \nosubgrouping
+ */
+ template <typename T_>
+ class PALUDIS_VISIBLE Cloneable
+ {
+ public:
+ ///\name Cloning
+ ///\{
+
+ /**
+ * Return a new copy of ourselves.
+ */
+ virtual tr1::shared_ptr<T_> clone() const PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
+
+ ///\}
+
+ ///\name Basic operations
+ ///\{
+
+ virtual ~Cloneable();
+
+ ///\}
+ };
+
+ /**
+ * Helper class implementing the clone() method using the copy
+ * contructor.
+ *
+ * \ingroup grpclone
+ * \nosubgrouping
+ */
+ template <typename Base_, typename Child_>
+ class PALUDIS_VISIBLE CloneUsingThis :
+ public virtual Cloneable<Base_>
+ {
+ public:
+ virtual tr1::shared_ptr<Base_> clone() const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ ///\name Basic operations
+ ///\{
+
+ virtual ~CloneUsingThis();
+
+ ///\}
+ };
+}
+
+#endif
+
+
diff --git a/paludis/util/files.m4 b/paludis/util/files.m4
index a6bc53d..c9f554d 100644
--- a/paludis/util/files.m4
+++ b/paludis/util/files.m4
@@ -9,6 +9,7 @@ dnl `test', `impl', `testscript'. Note that there isn't much error checking done
dnl on this file at present...
add(`attributes', `hh')
+add(`clone', `hh', `impl')
add(`collection', `hh', `fwd')
add(`collection_concrete', `hh')
add(`destringify', `hh', `cc', `test')