From: Tudor Bosman Date: Mon, 16 Jul 2012 03:13:19 +0000 (-0700) Subject: Add wrapper macros for "final" and "override" X-Git-Tag: v0.22.0~1237 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;ds=sidebyside;h=3e0db1be8cd3051dae5b100021b00575e154f988;p=folly.git Add wrapper macros for "final" and "override" 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 --- diff --git a/folly/Portability.h b/folly/Portability.h index 44f352d6..6d373a2c 100644 --- a/folly/Portability.h +++ b/folly/Portability.h @@ -26,5 +26,27 @@ #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 index 00000000..a6717dd5 --- /dev/null +++ b/folly/test/PortabilityTest.cpp @@ -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 + +#include + +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 p(new Derived); + EXPECT_EQ(3, fooBase(p.get())); + EXPECT_EQ(3, fooDerived(p.get())); +} +