Add wrapper macros for "final" and "override"
authorTudor Bosman <tudorb@fb.com>
Mon, 16 Jul 2012 03:13:19 +0000 (20:13 -0700)
committerJordan DeLong <jdelong@fb.com>
Thu, 2 Aug 2012 08:52:32 +0000 (01:52 -0700)
Summary:
... which are supported in gcc 4.7, but not 4.6, and they enable useful
optimizations.  As long as we're planning to support both 4.6 and 4.7 in
our code base, we should write code using these macros.

Test Plan:
test added, compiled with both 4.6 and 4.7, verified the
assertion in the test comment by looking at dissassembly output in the
4.7 version

Reviewed By: delong.j@fb.com

FB internal diff: D520343

folly/Portability.h
folly/test/PortabilityTest.cpp [new file with mode: 0644]

index 44f352d6b10bd2f994492c02c657b046e318e3a3..6d373a2cef8840a5fb9aed3d37b6c3bb5195d56c 100644 (file)
  #endif
 #endif
 
+// Define macro wrappers for C++11's "final" and "override" keywords, which
+// are supported in gcc 4.7 but not gcc 4.6.
+//
+// TODO(tudorb/agallagher): Autotoolize this.
+#undef FOLLY_FINAL
+#undef FOLLY_OVERRIDE
+
+#ifdef __GNUC__
+# if __GNUC_PREREQ(4,7)
+#  define FOLLY_FINAL final
+#  define FOLLY_OVERRIDE override
+# endif
+#endif
+
+#ifndef FOLLY_FINAL
+# define FOLLY_FINAL
+#endif
+
+#ifndef FOLLY_OVERRIDE
+# define FOLLY_OVERRIDE
+#endif
+
 
 #endif // FOLLY_PORTABILITY_H_
diff --git a/folly/test/PortabilityTest.cpp b/folly/test/PortabilityTest.cpp
new file mode 100644 (file)
index 0000000..a6717dd
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2012 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "folly/Portability.h"
+
+#include <memory>
+
+#include <gtest/gtest.h>
+
+class Base {
+ public:
+  virtual ~Base() { }
+  virtual int foo() const { return 1; }
+};
+
+class Derived : public Base {
+ public:
+  virtual int foo() const FOLLY_FINAL { return 2; }
+};
+
+// A compiler that supports final will likely inline the call to p->foo()
+// in fooDerived (but not in fooBase) as it knows that Derived::foo() can
+// no longer be overridden.
+int fooBase(const Base* p) { return p->foo() + 1; }
+int fooDerived(const Derived* p) { return p->foo() + 1; }
+
+TEST(Portability, Final) {
+  std::unique_ptr<Derived> p(new Derived);
+  EXPECT_EQ(3, fooBase(p.get()));
+  EXPECT_EQ(3, fooDerived(p.get()));
+}
+