From 1bd51e397a85e5de71d9cea2aabefbc3beef91f0 Mon Sep 17 00:00:00 2001
From: Adam Wardynski <award@.(win7-laptop)>
Date: Thu, 18 Nov 2010 22:33:19 +0100
Subject: [PATCH] Change static consts True and False to functions. Somewhat
 nicer to use and guards against static init order fiasco.

---
 libwccl/ops/and.cpp         |  4 ++--
 libwccl/ops/equals.h        | 10 +++++-----
 libwccl/ops/intersects.h    |  4 ++--
 libwccl/ops/issubsetof.h    |  4 ++--
 libwccl/ops/nor.cpp         |  4 ++--
 libwccl/ops/or.cpp          |  4 ++--
 libwccl/ops/predicate.cpp   | 12 ++++++++++--
 libwccl/ops/predicate.h     |  8 ++++----
 libwccl/ops/regex.cpp       | 10 +++++-----
 tests/logicalpredicates.cpp |  4 ++--
 10 files changed, 36 insertions(+), 28 deletions(-)

diff --git a/libwccl/ops/and.cpp b/libwccl/ops/and.cpp
index 0e119a7..7cf39ec 100644
--- a/libwccl/ops/and.cpp
+++ b/libwccl/ops/and.cpp
@@ -9,10 +9,10 @@ And::BaseRetValPtr And::apply_internal(const FunExecContext& context) const
 {
 	foreach(boost::shared_ptr< Function<Bool> > expression, *expressions_) {
 		if(!(expression->apply(context)->get_value())) {
-			return Predicate::False->apply(context);
+			return Predicate::False(context);
 		}
 	}
-	return Predicate::True->apply(context);
+	return Predicate::True(context);
 }
 
 const std::string And::raw_operator_name() const {
diff --git a/libwccl/ops/equals.h b/libwccl/ops/equals.h
index 0b1b6d4..c646208 100644
--- a/libwccl/ops/equals.h
+++ b/libwccl/ops/equals.h
@@ -47,9 +47,9 @@ protected:
 		boost::shared_ptr<T> arg1 = this->arg1_expr_->apply(context);
 		boost::shared_ptr<T> arg2 = this->arg2_expr_->apply(context);
 		if(arg1->equals(*arg2)) {
-			return Predicate::True->apply(context);
+			return Predicate::True(context);
 		}
-		return Predicate::False->apply(context);
+		return Predicate::False(context);
 	}
 };
 
@@ -94,17 +94,17 @@ protected:
 		boost::shared_ptr<Position> arg1 = this->arg1_expr_->apply(context);
 		boost::shared_ptr<Position> arg2 = this->arg2_expr_->apply(context);
 		if(arg1->equals(*arg2)) {
-			return Predicate::True->apply(context);
+			return Predicate::True(context);
 		} else {
 			//in the given context both positions can still point nowhere
 			//even if they have different underlying value
 			int abs_pos1 = context.get_abs_position(*arg1);
 			int abs_pos2 = context.get_abs_position(*arg2);
 			if(!context.is_inside(abs_pos1) && !context.is_inside(abs_pos2)) {
-				return Predicate::True->apply(context);
+				return Predicate::True(context);
 			}
 		}
-		return Predicate::False->apply(context);
+		return Predicate::False(context);
 	}
 };
 
diff --git a/libwccl/ops/intersects.h b/libwccl/ops/intersects.h
index 9a3a160..ad4716d 100644
--- a/libwccl/ops/intersects.h
+++ b/libwccl/ops/intersects.h
@@ -30,9 +30,9 @@ protected:
 		boost::shared_ptr<T> set1 = this->set1_expr_->apply(context);
 		boost::shared_ptr<T> set2 = this->set2_expr_->apply(context);
 		if(set1->is_subset_of(*set2)) {
-			return Predicate::True->apply(context);
+			return Predicate::True(context);
 		}
-		return Predicate::False->apply(context);
+		return Predicate::False(context);
 	}
 
 };
diff --git a/libwccl/ops/issubsetof.h b/libwccl/ops/issubsetof.h
index 685e833..a16622c 100644
--- a/libwccl/ops/issubsetof.h
+++ b/libwccl/ops/issubsetof.h
@@ -35,10 +35,10 @@ protected:
 		if(!possible_subset->empty()) {
 			boost::shared_ptr<T> set_compared_to = this->set2_expr_->apply(context);
 			if(possible_subset->is_subset_of(*set_compared_to)) {
-				return Predicate::True->apply(context);
+				return Predicate::True(context);
 			}
 		}
-		return Predicate::False->apply(context);
+		return Predicate::False(context);
 	}
 
 };
diff --git a/libwccl/ops/nor.cpp b/libwccl/ops/nor.cpp
index 4798819..50a8a4c 100644
--- a/libwccl/ops/nor.cpp
+++ b/libwccl/ops/nor.cpp
@@ -8,10 +8,10 @@ Nor::BaseRetValPtr Nor::apply_internal(const FunExecContext& context) const
 {
 	foreach(BoolFunctionPtr expression, *expressions_) {
 		if(expression->apply(context)->get_value()) {
-			return Predicate::False->apply(context);
+			return Predicate::False(context);
 		}
 	}
-	return Predicate::True->apply(context);
+	return Predicate::True(context);
 }
 
 const std::string Nor::raw_operator_name() const {
diff --git a/libwccl/ops/or.cpp b/libwccl/ops/or.cpp
index bdce8c6..af3d03e 100644
--- a/libwccl/ops/or.cpp
+++ b/libwccl/ops/or.cpp
@@ -8,10 +8,10 @@ Or::BaseRetValPtr Or::apply_internal(const FunExecContext& context) const
 {
 	foreach(BoolFunctionPtr expression, *expressions_) {
 		if(expression->apply(context)->get_value()) {
-			return Predicate::True->apply(context);
+			return Predicate::True(context);
 		}
 	}
-	return Predicate::False->apply(context);
+	return Predicate::False(context);
 }
 
 const std::string Or::raw_operator_name() const {
diff --git a/libwccl/ops/predicate.cpp b/libwccl/ops/predicate.cpp
index 66b0fb2..57d5ee1 100644
--- a/libwccl/ops/predicate.cpp
+++ b/libwccl/ops/predicate.cpp
@@ -2,8 +2,16 @@
 
 namespace Wccl {
 
-const boost::scoped_ptr< Constant<Bool> > Predicate::True(new Constant<Bool>(Bool(true)));
+Predicate::RetValPtr Predicate::True(const FunExecContext& context)
+{
+	static Constant<Bool> true_constant(Bool(true));
+	return true_constant.apply(context);
+}
 
-const boost::scoped_ptr< Constant<Bool> > Predicate::False(new Constant<Bool>(Bool(false)));
+Predicate::RetValPtr Predicate::False(const FunExecContext& context)
+{
+	static Constant<Bool> false_constant(Bool(false));
+	return false_constant.apply(context);
+}
 
 } /* end ns Wccl */
diff --git a/libwccl/ops/predicate.h b/libwccl/ops/predicate.h
index f064bee..e6176ff 100644
--- a/libwccl/ops/predicate.h
+++ b/libwccl/ops/predicate.h
@@ -14,13 +14,13 @@ namespace Wccl {
 class Predicate : public Function<Bool> {
 public:
 	/**
-	 * Constant<Bool> holding true value, to use by predicates when returning value
+	 * Helper function returing True, to use by predicates when returning value
 	 */
-	static const boost::scoped_ptr< Constant<Bool> > True;
+	static RetValPtr True(const FunExecContext& context);
 	/**
-	 * Constant<Bool> holding false value, to use by predicates when returning value
+	 * Helper function returing False, to use by predicates when returning value
 	 */
-	static const boost::scoped_ptr< Constant<Bool> > False;
+	static RetValPtr False(const FunExecContext& context);
 };
 
 } /* end ns Wccl */
diff --git a/libwccl/ops/regex.cpp b/libwccl/ops/regex.cpp
index 4759ea9..c059324 100644
--- a/libwccl/ops/regex.cpp
+++ b/libwccl/ops/regex.cpp
@@ -75,25 +75,25 @@ std::string Regex::to_raw_string() const {
 Regex::BaseRetValPtr Regex::apply_internal(const FunExecContext& context) const {
 	const boost::shared_ptr<const StrSet>& set = strset_expr_->apply(context);
 	if(set->empty()) {
-		return Predicate::False->apply(context);
+		return Predicate::False(context);
 	}
 	foreach(const UnicodeString& s, set->contents()) {
 		UErrorCode status = U_ZERO_ERROR;
 		boost::scoped_ptr<RegexMatcher> matcher(pattern_->matcher(s, status));
 		if(status != U_ZERO_ERROR) {
 			BOOST_ASSERT(status == U_ZERO_ERROR);
-			return Predicate::False->apply(context);
+			return Predicate::False(context);
 		}
 		bool matched = matcher->matches(status);
 		if(status != U_ZERO_ERROR) {
 			BOOST_ASSERT(status == U_ZERO_ERROR);
-			return Predicate::False->apply(context);
+			return Predicate::False(context);
 		}
 		if(!matched) {
-			return Predicate::False->apply(context);
+			return Predicate::False(context);
 		}
 	}
-	return Predicate::True->apply(context);
+	return Predicate::True(context);
 }
 
 } /* end ns Wccl */
diff --git a/tests/logicalpredicates.cpp b/tests/logicalpredicates.cpp
index 0de82f5..b400bc8 100644
--- a/tests/logicalpredicates.cpp
+++ b/tests/logicalpredicates.cpp
@@ -40,8 +40,8 @@ struct PredFix
 
 BOOST_FIXTURE_TEST_CASE(predicate_constants, PredFix)
 {
-	BOOST_CHECK_EQUAL(true, Predicate::True->apply(cx)->get_value());
-	BOOST_CHECK_EQUAL(false, Predicate::False->apply(cx)->get_value());
+	BOOST_CHECK_EQUAL(true, Predicate::True(cx)->get_value());
+	BOOST_CHECK_EQUAL(false, Predicate::False(cx)->get_value());
 }
 
 BOOST_FIXTURE_TEST_CASE(and_1arg, PredFix)
-- 
GitLab