From 1014462963f3a15a191228dd7f42375b55dbdd25 Mon Sep 17 00:00:00 2001
From: Adam Wardynski <award@.(win7-laptop)>
Date: Thu, 18 Nov 2010 18:36:24 +0100
Subject: [PATCH] Const contract on function return Value. Generally we want to
 avoid accidental change of value of a constant or of a variable. Originally
 I'd copy value on access, but this changed it so a const Value is returned
 instead and copy is done only when it's needed.

---
 libwccl/ops/affix.cpp    |  2 +-
 libwccl/ops/constant.h   |  7 +++----
 libwccl/ops/functions.h  |  8 ++++----
 libwccl/ops/regex.cpp    |  2 +-
 libwccl/ops/tolower.cpp  |  4 ++--
 libwccl/ops/toupper.cpp  |  2 +-
 tests/constant_tests.cpp | 10 ----------
 7 files changed, 12 insertions(+), 23 deletions(-)

diff --git a/libwccl/ops/affix.cpp b/libwccl/ops/affix.cpp
index 59562af..934787d 100644
--- a/libwccl/ops/affix.cpp
+++ b/libwccl/ops/affix.cpp
@@ -25,7 +25,7 @@ Affix::BaseRetValPtr Affix::apply_internal(const FunExecContext& context) const
 	if(affix_length_ == 0) {
 		return strset_expr_->apply(context);
 	}
-	const boost::shared_ptr<StrSet>& set = strset_expr_->apply(context);
+	const boost::shared_ptr<const StrSet>& set = strset_expr_->apply(context);
 	boost::shared_ptr<StrSet> a_set = boost::shared_ptr<StrSet>(new StrSet());
 	if(affix_length_ < 0) {
 		foreach(const UnicodeString& s, set->contents()) {
diff --git a/libwccl/ops/constant.h b/libwccl/ops/constant.h
index c5c933f..c9bb5d8 100644
--- a/libwccl/ops/constant.h
+++ b/libwccl/ops/constant.h
@@ -1,7 +1,6 @@
 #ifndef LIBWCCL_OPS_CONSTANT_H
 #define LIBWCCL_OPS_CONSTANT_H
 
-#include <boost/scoped_ptr.hpp>
 #include <boost/concept_check.hpp>
 
 #include <libwccl/ops/functions.h>
@@ -45,12 +44,12 @@ protected :
 	/**
 	 * Applying Constant function returns the held value of a constant
 	 */
-	virtual BaseRetValPtr  apply_internal(const FunExecContext&) const {
-		return BaseRetValPtr (new T(*value_));
+	BaseRetValPtr apply_internal(const FunExecContext&) const {
+		return value_;
 	}
 
 private:
-	const boost::scoped_ptr<const T> value_;
+	const boost::shared_ptr<const T> value_;
 };
 
 
diff --git a/libwccl/ops/functions.h b/libwccl/ops/functions.h
index 34acfe0..bda8751 100644
--- a/libwccl/ops/functions.h
+++ b/libwccl/ops/functions.h
@@ -17,9 +17,9 @@ namespace Wccl {
  */
 class FunctionBase : public Operator {
 protected:
-	typedef boost::shared_ptr<Value> BaseRetValPtr;
+	typedef boost::shared_ptr<const Value> BaseRetValPtr;
 	/**
-	 * Applies the function, given the sentence context.
+	 * Applies the function for the given execution context.
 	 */
 	virtual BaseRetValPtr apply_internal(const FunExecContext& context) const = 0;
 };
@@ -37,7 +37,7 @@ public:
 	 * Type returned after application of function (shared pointer to
 	 * a variable of the specified return type)
 	 */
-	typedef boost::shared_ptr<T> RetValPtr;
+	typedef boost::shared_ptr<const T> RetValPtr;
 
 	/**
 	 * Applies the function, given the sentence context, returning specific
@@ -45,7 +45,7 @@ public:
 	 * be specified in derived classes.
 	 */
 	RetValPtr apply(const FunExecContext& context) const {
-		RetValPtr v = boost::dynamic_pointer_cast<T>(apply_internal(context));
+		RetValPtr v = boost::dynamic_pointer_cast<const T>(apply_internal(context));
 		BOOST_ASSERT(v);
 		return v;
 	}
diff --git a/libwccl/ops/regex.cpp b/libwccl/ops/regex.cpp
index 0c4dca7..4759ea9 100644
--- a/libwccl/ops/regex.cpp
+++ b/libwccl/ops/regex.cpp
@@ -73,7 +73,7 @@ std::string Regex::to_raw_string() const {
 }
 
 Regex::BaseRetValPtr Regex::apply_internal(const FunExecContext& context) const {
-	const boost::shared_ptr<StrSet>& set = strset_expr_->apply(context);
+	const boost::shared_ptr<const StrSet>& set = strset_expr_->apply(context);
 	if(set->empty()) {
 		return Predicate::False->apply(context);
 	}
diff --git a/libwccl/ops/tolower.cpp b/libwccl/ops/tolower.cpp
index 52ad8c3..f88ce8a 100644
--- a/libwccl/ops/tolower.cpp
+++ b/libwccl/ops/tolower.cpp
@@ -12,8 +12,8 @@ std::string ToLower::to_raw_string() const {
 	return UnaryFunctionFormatter::to_raw_string(*this, *strset_expr_);
 }
 
-ToLower::BaseRetValPtr ToLower::apply_internal(const FunExecContext& context) const {
-	const boost::shared_ptr<StrSet >& set = strset_expr_->apply(context);
+ToLower::BaseRetValPtr ToLower::apply_internal(const FunExecContext& context) const {	
+	const boost::shared_ptr<const StrSet >& set = strset_expr_->apply(context);
 	boost::shared_ptr<StrSet > l_set = boost::make_shared<StrSet>();
 	//TODO: should tolower be a method of StrSet as well?
 	foreach(const UnicodeString& s, set->contents()) {
diff --git a/libwccl/ops/toupper.cpp b/libwccl/ops/toupper.cpp
index ec55211..edbc3c7 100644
--- a/libwccl/ops/toupper.cpp
+++ b/libwccl/ops/toupper.cpp
@@ -13,7 +13,7 @@ std::string ToUpper::to_raw_string() const {
 }
 
 ToUpper::BaseRetValPtr ToUpper::apply_internal(const FunExecContext& context) const {
-	const boost::shared_ptr<StrSet >& set = strset_expr_->apply(context);
+	const boost::shared_ptr<const StrSet >& set = strset_expr_->apply(context);
 	boost::shared_ptr<StrSet > u_set = boost::make_shared<StrSet>();
 	//TODO: should tolower be a method of StrSet as well?
 	foreach(const UnicodeString& s, set->contents()) {
diff --git a/tests/constant_tests.cpp b/tests/constant_tests.cpp
index b4754c7..08e1f02 100644
--- a/tests/constant_tests.cpp
+++ b/tests/constant_tests.cpp
@@ -58,14 +58,4 @@ BOOST_FIXTURE_TEST_CASE(bool_to_raw_string, BoolFix)
 	BOOST_CHECK_EQUAL(false_value.to_raw_string(), false_constant.to_raw_string());
 }
 
-BOOST_FIXTURE_TEST_CASE(bool_value_preserved, BoolFix)
-{
-	boost::shared_ptr<Bool> v = true_constant.apply(cx);
-	v->set_value(false);
-	BOOST_CHECK_EQUAL(true, true_constant.apply(cx)->get_value());
-	v = false_constant.apply(cx);
-	v->set_value(true);
-	BOOST_CHECK_EQUAL(false, false_constant.apply(cx)->get_value());
-}
-
 BOOST_AUTO_TEST_SUITE_END()
-- 
GitLab