lundi 27 juillet 2015

How to guard for TR1 on Apple platforms for both C++03 and C++11?

I'm catching a compile error when attempting to use unique_ptr on Apple platforms:

$ make
c++ -std=c++11 -DNDEBUG -g2 -O3 -fPIC -march=native -Wall -Wextra -pipe -c 3way.cpp
In file included ...
./smartptr.h:27:20: error: unknown type name 'unique_ptr'
  using auto_ptr = std::unique_ptr<T>;
                   ^
./smartptr.h:27:30: error: expected ';' after alias declaration
  using auto_ptr = std::unique_ptr<T>;

According to Marshall Clow, who I consider an expert on the C++ Standard Library with Clang and Apple:

Technical Report #1 (TR1) was a set of library additions to the C++03 standard. Representing the fact that they were not part of the "official" standard, they were placed in the namespace std::tr1.

In c++11, they are officially part of the standard, and live in the namespace std, just like vector and string. The include files no longer live in the "tr1" folder, either.

Take aways:

  • Apple and C++03 = use TR1 namespace
  • Apple and C++11 = use STD namespace
  • All others = use STD namespace

Now, here's what I have in smartptr.h:

#if (__cplusplus >= 201103L) // C++11
# include <memory>
#elif defined(__APPLE__) // C++03 and Apple
# include <tr1/memory>
#else // C++03 and everyone else
# include <memory>
#endif

// Manage auto_ptr warnings and deprecation in C++11
#if (__cplusplus >= 201103L)
  template<typename T>
    using auto_ptr = std::unique_ptr<T>;
#else
# if defined(__APPLE__)
  using std::tr1::auto_ptr;
# else
  using std::auto_ptr;
# endif // Apple
#endif // C++11

Obviously, Apple has things mangled worse than Marshall expects. (And the CFE Devs specifically told me to use that code; see Suggestion for C++ migration tool: tr1 removal on the CFE Dev mailing list).

The last thing to check is the __APPLE__ define, and here it is:

$ c++ -x c++ -dM -E - < /dev/null | grep -i apple
#define __APPLE_CC__ 6000
#define __APPLE__ 1
#define __VERSION__ "4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)"
#define __apple_build_version__ 5030040

How do I guard for TR1 on Apple platforms for both C++03 and C++11?

Aucun commentaire:

Enregistrer un commentaire