C++ standard library extensions

Currently, C++ standard library headers usage for CMake is normalized through the directory prefix cm. For example: #include <cm/memory>.

But, there is no clear approach regarding extensions to the standard library. For now, the header cmAlgorithms.h holds mainly extensions to the C++ standard library. But because it is located at the same place as the CMake code, it is not clear to determine the goal and usage of this header…

I propose the following approach to facilitate development and usage of standard library extensions:

  • Use directory prefix cmext.
  • Use same names as from standard library to hold related topics.
  • Store these new headers under Utilities/std/cmext.

And for the coding rules:

  • Use namespace cm. I think it is better to keep same namespace as CMake standard headers to show the close relationship with them.
  • use naming conventions from the standard library: all lowercase with underscores.

As an example, extensions to memory utilities (std::unique_ptr and std::shared_ptr) for conversion types (on the model of std::static_pointer_cast): cm::static_reference_cast and cm::dynamic_reference_cast

File Utilities/std/cmext/memory

#include <memory>

namespace cm
{
template <typename T, typename O>
T& static_reference_cast(O& item)
{
  return *(static_cast<T*>(item.get()));
}

template <typename T, typename O>
T& dynamic_reference_cast(O& item)
{
  return *(dynamic_cast<T*>(item.get()));
}
} // namespace cm

And for the usage (nota: including cmext/memory do not include automatically cm/memory):

#include <cm/memory>
#include <cmext/memory>

class Base
{}
class Derived : public Base
{
public:
   void func ();
}

std::unique_ptr<Base> up = cm::make_unique<Derived>();
cm::static_reference_cast<Derived>(up).func();

This sounds fine to me, though I’d be interested in others’ thoughts too.

Sounds fine to me too. If possible I’d like to see comments on the functions if/when they have future-C++ variants on their way in. That can help find code we can remove given a C++ standard bump in CMake itself.

I’d actually advise against using the same file names as the standard headers. It opens up too many possibilities for confusion. You have to be very careful not to add the directory that contains them to the header search path or else you can’t reach the same-named standard headers any more. Having experienced this exact problem in one or two projects, I’m keen to avoid even the chance of seeing that here.

I personally also find it a bit strange having to include both <cm/memory> and <cmext/memory>. If I’m wanting to include CMake’s helpers/replacements/stand-ins for the <memory> header, it seems odd that I would have to pull in two headers instead of just one to do that.

The headers under cmext are not dedicated to replace standard headers. This is the role of headers under cm which are a pure replacement of the standard ones.

Under cmext, are headers extending the capabilities of the standard library. There is currently already some extensions to <algorithm> in the file cmAlgorithms.h for example.

I agree that directory holding the headers must not be included but re-using same name enforce the strong relationship between the two headers.

@brad.king I will create a MR to show up a concrete example of this proposition.
What is the process for that? Is it required to create an issue or is it enough to add a link to this discussion in the MR?

@marc.chevrier references to this discussion are fine from the MR discussion posts, but if any commit messages need to reference discussion it’s best to have a numbered issue (whose number will survive future hosting platform changes).