// bsls_cpp11.h                                                       -*-C++-*-
#ifndef INCLUDED_BSLS_CPP11
#define INCLUDED_BSLS_CPP11

#include <bsls_ident.h>
BSLS_IDENT("$Id: $")

//@PURPOSE: Provide macros for C++11 forward compatibility.
//
//@DEPRECATED: Use 'bsls_keyword' instead.
//
//@CLASSES:
//
//@MACROS:
//  BSLS_CPP11_CONSTEXPR: C++11 'constexpr' keyword
//  BSLS_CPP11_DELETED: C++11 '= delete' function definition
//  BSLS_CPP11_EXPLICIT: C++11 'explicit' for conversion operators
//  BSLS_CPP11_FINAL: C++11 'final' keyword
//  BSLS_CPP11_NOEXCEPT: C++11 'noexcept' keyword
//  BSLS_CPP11_NOEXCEPT_AVAILABLE: 'C++11' 'noexcept' flag
//  BSLS_CPP11_NOEXCEPT_SPECIFICATION(...): C++11 'noexcept' function qualifier
//  BSLS_CPP11_NOEXCEPT_OPERATOR(expr): C++11 'noexcept' operation
//  BSLS_CPP11_OVERRIDE: C++11 'override' keyword
//  BSLS_CPP11_PROVISIONALLY_FALSE: C++11 specification placeholder
//
//@DESCRIPTION: This component provides definitions to use C++11 features in
// both C++03 and C++11 without using conditional compilation where the
// features are used.  The goal is to allow implementation of components such
// that they can take advantage of some C++11 features when compiled with C++11
// mode enabled while also correctly compiling in C++03 mode.  The
// functionality of the respective features won't be available in C++03 mode.
//
///Macro Summary
///-------------
// The following are the macros provided by this component.
//
//: 'BSLS_CPP11_CONSTEXPR':
//:     !DEPRECATED!: Use 'BSLS_KEYWORD_CONSTEXPR' instead.  This macro inserts
//:     the keyword 'constexpr' when compiling with C++11 mode and inserts
//:     nothing when compiling with C++03 mode.
//:
//: 'BSLS_CPP11_DELETED':
//:     !DEPRECATED!: Use 'BSLS_KEYWORD_DELETED' instead.  This macro inserts
//:     the text '= delete' when compiling with C++11 mode and inserts nothing
//:     when compiling with C++03 mode.
//:
//: 'BSLS_CPP11_EXPLICIT':
//:     !DEPRECATED!: Use 'BSLS_KEYWORD_EXPLICIT' instead.  This macro inserts
//:     the keyword 'explicit' when compiling with C++11 mode and inserts
//:     nothing when compiling with C++03 mode.
//:
//: 'BSLS_CPP11_FINAL':
//:     !DEPRECATED!: Use 'BSLS_KEYWORD_FINAL' instead.  This macro inserts the
//:     keyword 'final' when compiling with C++11 mode and inserts nothing when
//:     compiling with C++03 mode.
//:
//: 'BSLS_CPP11_NOEXCEPT':
//:     !DEPRECATED!: Use 'BSLS_KEYWORD_NOEXCEPT' instead.  This macro inserts
//:     the keyword 'noexcept' when compiling with C++11 mode and inserts
//:     nothing when compiling with C++03 mode.
//:
//: 'BSLS_CPP11_NOEXCEPT_AVAILABLE':
//:     !DEPRECATED!: Use 'BSLS_KEYWORD_NOEXCEPT_AVAILABLE' instead.  This
//:     macro expands to 'true' when the 'noexcept' feature is available and
//:     'false' otherwise.
//:
//: 'BSLS_CPP11_NOEXCEPT_SPECIFICATION(BOOL_EXPRESSION)':
//:     !DEPRECATED!: Use 'BSLS_KEYWORD_NOEXCEPT_SPECIFICATION' instead.  This
//:     macro inserts the exception specification 'noexcept(BOOL_EXPRESSION)'
//:     when compiling with C++11 mode and inserts nothing when compiling with
//:     C++03 mode.  This macro is used to specify which version of 'noexcept'
//:     is intended when multiple 'noexcept's are used in a single statement.
//:
//: 'BSLS_CPP11_NOEXCEPT_OPERATOR(expr)':
//:     !DEPRECATED!: Use 'BSLS_KEYWORD_NOEXCEPT_OPERATOR' instead.  This macro
//:     inserts the operation 'noexcept(expr)' when compiling with C++11 mode
//:     and inserts the literal 'false' when compiling with C++03 mode.
//:
//: 'BSLS_CPP11_OVERRIDE'
//:     !DEPRECATED!: Use 'BSLS_KEYWORD_OVERRIDE' instead.  This macro inserts
//:     the keyword 'override' when compiling with C++11 mode and inserts
//:     nothing when compiling with C++03 mode.
//:
//: 'BSLS_CPP11_PROVISIONALLY_FALSE':
//:     !DEPRECATED!: Use 'false' instead.  This macro inserts the keyword
//:     'false'.  This macro is intended to be used as a placeholder in the
//:     'BSLS_CPP11_NOEXCEPT_SPECIFICATION(BOOL_EXPRESSION)' macro when
//:     traits needed for 'BOOL_EXPRESSION' have not yet been implemented.
//
///Usage
///-----
// This section illustrates intended use of this component.
//
///Example 1: Preparing C++03 Code for C++11 Features
/// - - - - - - - - - - - - - - - - - - - - - - - - -
// To use these macros, simply insert them where the corresponding C++11
// keyword would go.  When compiling with C++03 mode there will be no effect
// but when compiling with C++11 mode additional restrictions will apply.  When
// compiling with C++11 mode the restriction will be checked providing some
// additional checking over what is done with C++11.
//
// C++ uses the 'explicit' keyword to indicate that constructors taking just
// one argument are not considered for implicit conversions.  Instead, they can
// only be used for explicit conversions.  C++ also provides the ability to
// define conversion operators but prior to C++11 these conversion operators
// are considered for implicit conversion.  C++11 allows the use of the
// 'explicit' keyword with conversion operators to avoid its use for implicit
// conversions.  The macro 'BSLS_CPP11_EXPLICIT' can be used to mark
// conversions as explicit conversions which will be checked when compiling
// with C++11 mode.  For example, an 'Optional' type may have an explicit
// conversion to 'bool' to indicate that the value is set (note the conversion
// operator):
//..
//  template <class TYPE>
//  class Optional
//  {
//      TYPE* d_value;
//  public:
//      Optional(): d_value() {}
//      explicit Optional(const TYPE& value): d_value(new TYPE(value)) {}
//      ~Optional() { delete d_value; }
//      // ...
//
//      BSLS_CPP11_EXPLICIT operator bool() const { return d_value; }
//  };
//..
// When using an object of the 'Optional' class in a condition it is desirable
// that it converts to a 'bool':
//..
//  Optional<int> value;
//  if (value) { /*... */ }
//..
// In places where an implicit conversion takes place it is not desirable that
// the conversion is used.  When compiling with C++11 mode the conversion
// operator will not be used, e.g., the following code will result in an error:
//..
//  bool flag = value;
//..
// When defining conversion operators to 'bool' for code which needs to compile
// with C++03 mode the conversion operator should convert to a member pointer
// type instead: doing so has a similar effect to making the conversion
// operator 'explicit'.
//
// Some classes are not intended for use as a base class.  To clearly label
// these classes and enforce that they can't be derived from C++11 allows using
// the 'final' keyword after the class name in the class definition to label
// classes which are not intended to be derived from.  The macro
// 'BSLS_CPP11_FINAL' is replaced by 'final' when compiling with C++11 causing
// the compiler to enforce that a class can't be further derived.  The code
// below defines a class which can't be derived from:
//..
//  class FinalClass BSLS_CPP11_FINAL
//  {
//      int d_value;
//    public:
//      explicit FinalClass(int value = 0): d_value(value) {}
//      int value() const { return d_value; }
//  };
//..
// An attempt to derive from this class will fail when compiling with C++11
// mode:
//..
//  class FinalClassDerived: public FinalClass {
//      int d_anotherValue;
//  public:
//      explicit FinalClassDerived(int value)
//          : d_anotherValue(2 * value) {
//      }
//      int anotherValue() const { return d_anotherValue; }
//  };
//..
// The code will compile successfully when using C++03 mode.
//
// Sometime it is useful to declare that an overriding function is the final
// overriding function and further derived classes won't be allowed to further
// override the function.  One use of this feature could be informing the
// compiler that it won't need to use virtual dispatch when calling this
// function on a pointer or a reference of the corresponding type.  C++11
// allows marking functions as the final overrider using the keyword 'final'.
// The macro 'BSLS_CPP11_FINAL' can also be used for this purpose.  To
// demonstrate the use of this keyword first a base class with a 'virtual'
// function is defined:
//..
//  struct FinalFunctionBase
//  {
//      virtual int f() { return 0; }
//  };
//..
// When defining a derived class this function 'f' can be marked as the final
// overrider using 'BSLS_CPP11_FINAL':
//..
//  struct FinalFunctionDerived: FinalFunctionBase
//  {
//      int f() BSLS_CPP11_FINAL { return 1; }
//  };
//..
// The semantics of the overriding function aren't changed but a further
// derived class can't override the function 'f', i.e., the following code will
// result in an error when compiling with C++11 mode:
//..
//  struct FinalFunctionFailure: FinalFunctionDerived
//  {
//      int f() { return 2; }
//  };
//..
// With C++03 mode the code will successfully compile.
//
// The C++11 keyword 'override' is used to identify functions overriding a
// 'virtual' function from a base class.  If a function identified as
// 'override' does not override a 'virtual' function from a base class the
// compilation results in an error.  The macro 'BSLS_CPP11_OVERRIDE' is used to
// insert the 'override' keyword when compiling with C++11 mode.  When
// compiling with C++03 mode it has no effect but it both cases it documents
// that a function is overriding a 'virtual' function from a base class.  To
// demonstrate the use of the 'BSLS_CPP11_OVERRIDE' macro first a base class is
// defined:
//..
//  struct OverrideBase
//  {
//      virtual int f() const { return 0; }
//  };
//..
// When overriding 'OverrideBase::f' in a derived class the
// 'BSLS_CPP11_OVERRIDE' macro should be used to ascertain that the function in
// the derived class is indeed overriding a 'virtual' function:
//..
//  struct OverrideSuccess: OverrideBase
//  {
//      int f() const BSLS_CPP11_OVERRIDE { return 1; }
//  };
//..
// The above code compiles successfully with both C++03 mode and C++11.  When
// the function meant to be an override actually isn't overriding any function
// the compilation will fail when using C++11 mode as is demonstrated by the
// following example (note the missing 'const' in the function declaration):
//..
//  struct OverrideFailure: OverrideBase
//  {
//      int f() BSLS_CPP11_OVERRIDE { return 2; }
//  };
//..

#include <bsls_keyword.h>

#define BSLS_CPP11_CONSTEXPR BSLS_KEYWORD_CONSTEXPR

#define BSLS_CPP11_DELETED BSLS_KEYWORD_DELETED

#define BSLS_CPP11_NOEXCEPT BSLS_KEYWORD_NOEXCEPT
#define BSLS_CPP11_NOEXCEPT_AVAILABLE BSLS_KEYWORD_NOEXCEPT_AVAILABLE
#define BSLS_CPP11_NOEXCEPT_SPECIFICATION(...) \
                               BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(__VA_ARGS__)
#define BSLS_CPP11_NOEXCEPT_OPERATOR(...) \
                                    BSLS_KEYWORD_NOEXCEPT_OPERATOR(__VA_ARGS__)
#define BSLS_CPP11_PROVISIONALLY_FALSE false

#define BSLS_CPP11_EXPLICIT BSLS_KEYWORD_EXPLICIT

#define BSLS_CPP11_FINAL BSLS_KEYWORD_FINAL

#define BSLS_CPP11_OVERRIDE BSLS_KEYWORD_OVERRIDE

// ----------------------------------------------------------------------------

#endif

// ----------------------------------------------------------------------------
// Copyright 2015 Bloomberg Finance L.P.
//
// 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.
// ----------------------------- END-OF-FILE ----------------------------------