Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Find alternatives to the current C++ smart pointers implementation based on loki #48

Open
javarias opened this issue Apr 8, 2016 · 2 comments

Comments

@javarias
Copy link
Collaborator

javarias commented Apr 8, 2016

The current C++ smart pointer is based on loki libraries, see loki webpage.
In modern C++ standards (C++11 and C++17 ) a new set of standard smart pointers have been accepted and introduced as part of the C++ standard libraries, which are listed here. The modern C++ standards are support in newer versions of GCC than the one include in CentOS 6, for this reason we should look for an alternative until CentOS and/or RHEL supports the newer compilers.

The C++ smart pointers are mostly based on versions of smart pointers developed by boost libraries, which should be compatible with the newest C++ standards, providing a simple upgrade path to C++ smart pointers when time comes.

@patbrandt
Copy link

In Boost 1.41, there is an implementation of unique_ptr hiding in boost/interprocess/smart_ptr/unique_ptr.hpp. It does not have move semantics, and in fact it seems to support the same copy semantics that auto_ptr does (transferred ownership). But on the plus side it does support custom deleters (which are very useful), and it has the same interface as the C++11 STL version. In later versions of boost it is in movelib (boost/move/unique_ptr.hpp).

There is also an implementation of shared_ptr in the same place, though you can also get that from TR1 in STL (<tr1/shared_ptr>, std::tr1::shared_ptr).

@patbrandt
Copy link

patbrandt commented Jun 9, 2016

The header below attempts to alias a version of unique_ptr, shared_ptr, and weak_ptr under a namespace (acs) to prevent global pollution. I've tested it successfully on RHEL6.7 with:

  • gcc4.4.7 with Boost 1.41
  • gcc4.4.7 with -std=c++0x
  • gcc5.2 with Boost 1.59
  • gcc5.2 with -std=c++11

And it (correctly) fails to provide unique_ptr while still supporting the other two on RHEL5.3 with gcc4.1.2 and Boost 1.33. One caveat: unfortunately the boost::interprocess::unique_ptr (Boost 1.35 through 1.56) requires a deleter to specified; there is no default. It's easy enough to define one though:

template <typename T>
void deleter(T *t) {
    delete t;
}

And then all the uses would look like:

acs::unique_ptr<TYPE, void(*)(TYPE*)> up(new TYPE, deleter<TYPE>);

A little unwieldy but this is all-around hacky anyways.

#ifndef modernSmartPtrs_H
#define modernSmartPtrs_H

#include <boost/version.hpp>
#define GCC_VERSION (__GNUC__ * 10000       \
                     + __GNUC_MINOR__ * 100 \
                     + __GNUC_PATCHLEVEL__)

// If C++11 is available, use the STL implementation
#if __cplusplus >= 201103L || \
    (__GNUC__ >= 4 && __GNUC_MINOR__ >= 4 && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \
    defined(__clang__)
#include <memory>
// Pack these into a namespace so they are not polluting globally
// when this header is included.
namespace acs {
using std::unique_ptr;
using std::shared_ptr;
using std::weak_ptr;
}// namespace acs

// Otherwise, fall back on the newest version of boost's
// implementation available
#elif defined(BOOST_VERSION)
// unique_ptr changed places in Boost 1.57, so determine
// where we should look for it
#if BOOST_VERSION >= 105700
#include <boost/move/unique_ptr.hpp>
namespace acs {
using boost::movelib::unique_ptr;
}// namespace acs
#elif BOOST_VERSION >= 103500
#include <boost/interprocess/smart_ptr/unique_ptr.hpp>
namespace acs {
using boost::interprocess::unique_ptr;
}// namespace acs
// If an older version of boost is found, simply omit unique_ptr support
#else
#warning "Using Boost older than 1.35; unique_ptr will not be available!"
#endif//BOOST_VERSION comparison

// Alias shared_ptr and weak_ptr as well
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
namespace acs {
using boost::shared_ptr;
using boost::weak_ptr;
}// namespace acs

// If we don't have C++11 or Boost, call it an error
// (It might be possible to fall back on TR1, but honestly
// trying to support all that logic for all the GCC versions
// is too much work. Setting the min version of GCC at 4.4 and/or
// Boost at 1.35 is more than reasonable.)
#else
#error "Upgrade your GCC version or install Boost to use this header!"
#endif//__cplusplus[...]

#undef GCC_VERSION

#endif//modernSmartPtrs_H

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants