teslamotors / fixed-containers

C++ Fixed Containers
MIT License
361 stars 31 forks source link

Support to C++ 14 #16

Closed prashantindalkar closed 1 year ago

prashantindalkar commented 1 year ago

Hello @alexkaratarakis, I am trying to use FixedMap for c++ 14. I am facing some issue in std::concepts ,is there any way to replace std::concepts. Or else how to migrate above source code into the c++ 14.

Need your help for same.

Thank You, Prashant Indalkar

alexkaratarakis commented 1 year ago

Hi @prashantindalkar , there are a few concepts at play here that you would need to address for C++14: 1) The one choosing between trivially_copyable vs not_trivially_copyable map implementation. It was recently introduced here to support erase_if(). erase_if() is a C++20 addition, so you can revert both of these. You can also keep erase_if() but keep in mind argument deduction is problematic with the std::conditional_t way of choosing between map implementations, so you will need to specify template parameters when using it. Also, for C++14, replace std::conditional_t with typename std::conditional<T>:type

2) OptionalStorage also uses concepts to choose between trivially_copyable vs not_trivially_copyable. You can go back to the old way of choosing via std::conditional_t. Similarly for IndexOrValueStorage.

3) concepts.hpp defines type_traits as concepts (e.g. std::trivially_copyable_v -> TriviallyCopyable). You can replace the keyword concept with inline constexpr in that file. Also, C++14 doesn't have the _v convenience bools (e.g. std::trivially_copyable_v), so you would instead have to do typename std::trivially_copyable::value. Interestingly, this header makes it a bit easier to get to your goal as you only have to change the traits here. Usages that require concepts like template<TriviallyCopyable T> class MyClass would have to be replaced with C++14 compatible ways (SFINAE, std::conditional_t etc)

There are also usages of the requires keyword, which is new in C++20. For normal functions, it can be replaced with SFINAE, but it also used for special member functions (constructors, assignment ops) which is more problematic. This is used in the non-trivially-copyable implementation of FixedMap and attempts to = default special functions to match triviality where appropriate (for example if K, V is trivially move constructible only, FixedMap<K,V> matches this by defaulting the move constructor). If this is not a requirement, you can remove these altogether, and the non-defaulted ones right below will take over. If K, V are trivially_copyable, then there is a dedicated implementation that doesn't use requires keyword so those FixedMap's will still be fully trivially_copyable. You can technically apply this pattern for additional implementations if you need "partial triviality" (via std::conditional from item 1), but the amount of possible combinations to fully achieve this is high.

An additional problem would be constexpr, as C++14 doesn't have extensive support for it, with syntactic limitations and even std::array not being fully constexpr. If you don't need constexpr for your use-case, you can remove the keyword as needed. If you need constexpr, you will need to provide custom implementations for appropriate std:: library bits and also adjust the code to the limitations of C++14.

prashantindalkar commented 1 year ago

@alexkaratarakis , Thank you so much for your help.

Thank you, Prashant Indalkar