From 1d86b36bfbc0da3267ae4f3a66a7c9714e334167 Mon Sep 17 00:00:00 2001 From: Mark Gillard Date: Fri, 25 Aug 2023 16:21:27 +0300 Subject: [PATCH] minor bugfixes + refactors --- CHANGELOG.md | 1 + docs/poxy.toml | 4 +- examples/entities.hpp | 325 ++++++------ examples/shapes.hpp | 824 +++++++++++++++---------------- src/soagen/header_file.py | 3 + src/soagen/hpp/iterator.hpp | 16 +- src/soagen/hpp/single/soagen.hpp | 141 ++---- src/soagen/hpp/table_traits.hpp | 125 ++--- src/soagen/main.py | 7 +- src/soagen/preprocessor.py | 6 + src/soagen/struct.py | 579 +++++++++++----------- tests/employees.hpp | 294 +++++------ 12 files changed, 1092 insertions(+), 1233 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d31e58..b29a1c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## v0.7.0 - Fixed rvalue row corruption bug on MSVC ([info](https://developercommunity.visualstudio.com/t/C:-Corrupt-references-when-creating-a/10446877)) +- Fuxed some SFINAE issues - Added `Cols...` selector template parameter to `at()`, `front()` and `back()` - Added `structs.mixins` - Added copy-based fallbacks for `unordered_erase()`, `insert()`, `emplace()` and `swap_columns()` (previously they required movability) diff --git a/docs/poxy.toml b/docs/poxy.toml index 2e20882..548476a 100644 --- a/docs/poxy.toml +++ b/docs/poxy.toml @@ -22,7 +22,7 @@ extra_files = [ 'images/author.jpg', ] stylesheets = ['pages.css'] -navbar = ['schema', 'pages', 'namespaces', 'classes'] +navbar = ['pages', 'namespaces', 'classes'] [warnings] enabled = true @@ -38,7 +38,7 @@ paths = [ 'pages', ] patterns = ['*.hpp', '*.dox', '*.md'] -strip_paths = ['../src/soagen/hpp', '../examples'] +strip_paths = ['../src/soagen/hpp', '../examples', 'pages'] # [examples] diff --git a/examples/entities.hpp b/examples/entities.hpp index b3385dd..46184a6 100644 --- a/examples/entities.hpp +++ b/examples/entities.hpp @@ -42,6 +42,9 @@ SOAGEN_DISABLE_SPAM_WARNINGS; #if defined(DOXYGEN) || defined(__DOXYGEN) || defined(__DOXYGEN__) || defined(__doxygen__) || defined(__POXY__) \ || defined(__poxy__) + #ifndef SOAGEN_CONSTRAINED_TEMPLATE + #define SOAGEN_CONSTRAINED_TEMPLATE(cond, ...) template <__VA_ARGS__> + #endif #ifndef SOAGEN_DOXYGEN #define SOAGEN_DOXYGEN 1 #endif @@ -246,11 +249,13 @@ namespace soagen::examples /// @brief Gets the soagen::column_traits for a specific column of the table. template - using column_traits = typename table_traits::template column(Column)>; + using column_traits = + POXY_IMPLEMENTATION_DETAIL(typename table_traits::template column(Column)>); /// @brief Gets the type of a specific column in the table. template - using column_type = typename column_traits(Column)>::value_type; + using column_type = + POXY_IMPLEMENTATION_DETAIL(typename column_traits(Column)>::value_type); /// @brief Row iterators returned by iterator functions. using iterator = soagen::iterator_type; @@ -409,11 +414,11 @@ namespace soagen::examples /// @brief Erases the row at the given position. /// /// @availability This method is only available when all the column types are move-assignable. - SOAGEN_HIDDEN(template >) + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = soagen::has_erase_member) SOAGEN_ALWAYS_INLINE SOAGEN_CPP20_CONSTEXPR // SOAGEN_ENABLE_IF_T(entities&, sfinae) erase(size_type pos) // - noexcept(soagen::has_nothrow_erase_member) + noexcept(soagen::has_nothrow_erase_member) // { table_.erase(pos); return *this; @@ -431,11 +436,11 @@ namespace soagen::examples /// @returns The position of the row that was moved into the erased row's position, if any. /// /// @availability This method is only available when all the column types are move-assignable. - SOAGEN_HIDDEN(template >) + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = soagen::has_unordered_erase_member) SOAGEN_ALWAYS_INLINE SOAGEN_CPP20_CONSTEXPR // SOAGEN_ENABLE_IF_T(soagen::optional, sfinae) unordered_erase(size_type pos) // - noexcept(soagen::has_nothrow_unordered_erase_member) + noexcept(soagen::has_nothrow_unordered_erase_member) // { return table_.unordered_erase(pos); } @@ -446,11 +451,11 @@ namespace soagen::examples /// or #end() if the one removed was the last row in the table. /// /// @availability This method is only available when all the column types are move-assignable. - SOAGEN_HIDDEN(template >) + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = soagen::has_erase_member) SOAGEN_ALWAYS_INLINE SOAGEN_CPP20_CONSTEXPR - SOAGEN_ENABLE_IF_T(iterator, sfinae) erase(iterator pos) // - noexcept(soagen::has_nothrow_erase_member) + SOAGEN_ENABLE_IF_T(iterator, sfinae) erase(iterator pos) // + noexcept(soagen::has_nothrow_erase_member) // { table_.erase(static_cast(pos)); return pos; @@ -468,11 +473,11 @@ namespace soagen::examples /// @returns The position of the row that was moved into the erased row's position, if any. /// /// @availability This method is only available when all the column types are move-assignable. - SOAGEN_HIDDEN(template >) + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = soagen::has_unordered_erase_member) SOAGEN_ALWAYS_INLINE SOAGEN_CPP20_CONSTEXPR SOAGEN_ENABLE_IF_T(soagen::optional, sfinae) unordered_erase(iterator pos) // - noexcept(soagen::has_nothrow_unordered_erase_member) + noexcept(soagen::has_nothrow_unordered_erase_member) // { if (auto moved_pos = table_.unordered_erase(static_cast(pos)); moved_pos) return iterator{ *this, static_cast(*moved_pos) }; @@ -485,11 +490,11 @@ namespace soagen::examples /// or #cend() if the one removed was the last row in the table. /// /// @availability This method is only available when all the column types are move-assignable. - SOAGEN_HIDDEN(template >) + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = soagen::has_erase_member) SOAGEN_ALWAYS_INLINE SOAGEN_CPP20_CONSTEXPR SOAGEN_ENABLE_IF_T(const_iterator, sfinae) erase(const_iterator pos) // - noexcept(soagen::has_nothrow_erase_member) + noexcept(soagen::has_nothrow_erase_member) // { table_.erase(static_cast(pos)); return pos; @@ -507,11 +512,11 @@ namespace soagen::examples /// @returns The position of the row that was moved into the erased row's position, if any. /// /// @availability This method is only available when all the column types are move-assignable. - SOAGEN_HIDDEN(template >) + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = soagen::has_unordered_erase_member) SOAGEN_ALWAYS_INLINE SOAGEN_CPP20_CONSTEXPR SOAGEN_ENABLE_IF_T(soagen::optional, sfinae) unordered_erase(const_iterator pos) // - noexcept(soagen::has_nothrow_unordered_erase_member) + noexcept(soagen::has_nothrow_unordered_erase_member) // { if (auto moved_pos = table_.unordered_erase(static_cast(pos)); moved_pos) return const_iterator{ *this, static_cast(*moved_pos) }; @@ -559,6 +564,8 @@ namespace soagen::examples /// @name Adding rows /// @{ + // ------ push_back() -------------------------------------------------------------------------- + /// @brief Adds a new row at the end of the table. SOAGEN_CPP20_CONSTEXPR entities& push_back(column_traits<0>::param_type id, @@ -575,14 +582,13 @@ namespace soagen::examples } /// @brief Adds a new row at the end of the table (rvalue overload). - SOAGEN_HIDDEN(template ) + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = table_traits::rvalues_are_distinct) SOAGEN_CPP20_CONSTEXPR - entities& push_back(SOAGEN_ENABLE_IF_T(column_traits<0>::rvalue_type, sfinae) id, + entities& push_back(column_traits<0>::rvalue_type id, column_traits<1>::rvalue_type name = "", column_traits<2>::rvalue_type pos = {}, column_traits<3>::rvalue_type orient = { 1, 0, 0, 0 }) // noexcept(table_traits::rvalue_push_back_is_nothrow) // - SOAGEN_REQUIRES(table_traits::rvalues_are_distinct) // { table_.emplace_back(static_cast::rvalue_forward_type>(id), static_cast::rvalue_forward_type>(name), @@ -591,16 +597,17 @@ namespace soagen::examples return *this; } + // ------ emplace_back() ----------------------------------------------------------------------- + /// @brief Constructs a new row directly in-place at the end of the table. - template ::default_emplace_type, - typename Pos = column_traits<2>::default_emplace_type, - typename Orient = column_traits<3>::default_emplace_type SOAGEN_ENABLE_IF( - table_traits::row_constructible_from)> + SOAGEN_CONSTRAINED_TEMPLATE((table_traits::row_constructible_from), // + typename Id, + typename Name = column_traits<1>::default_emplace_type, + typename Pos = column_traits<2>::default_emplace_type, + typename Orient = column_traits<3>::default_emplace_type) // SOAGEN_CPP20_CONSTEXPR entities& emplace_back(Id&& id, Name&& name = "", Pos&& pos = {}, Orient&& orient = { 1, 0, 0, 0 }) // noexcept(table_traits::emplace_back_is_nothrow) // - SOAGEN_REQUIRES(table_traits::row_constructible_from) // { table_.emplace_back(static_cast(id), static_cast(name), @@ -610,11 +617,10 @@ namespace soagen::examples } /// @brief Constructs a new row directly in-place at the end of the table by unpacking a tuple-like object. - template )> + SOAGEN_CONSTRAINED_TEMPLATE(table_traits::row_constructible_from, typename Tuple) SOAGEN_CPP20_CONSTEXPR entities& emplace_back(Tuple&& tuple_) // noexcept(table_traits::emplace_back_is_nothrow) // - SOAGEN_REQUIRES(table_traits::row_constructible_from) // { table_.emplace_back(static_cast(tuple_)); return *this; @@ -623,23 +629,33 @@ namespace soagen::examples /// @} /// @name Inserting rows - /// @availability These overloads are only available when all the column types are move-constructible and move-assignable. + /// @availability These overloads are only available when all the column types are move/copy-constructible and move/copy-assignable. /// @{ + private: + /// @cond + + static constexpr bool can_insert_ = + table_traits::all_move_or_copy_constructible && table_traits::all_move_or_copy_assignable; + + static constexpr bool can_insert_rvalues_ = can_insert_ && table_traits::rvalues_are_distinct; + + /// @endcond + + public: + // ------ insert(size_type) -------------------------------------------------------------------- + /// @brief Inserts a new row at an arbitrary position in the table. /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - SOAGEN_HIDDEN(template - ) + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = can_insert_) // SOAGEN_CPP20_CONSTEXPR SOAGEN_ENABLE_IF_T(entities&, sfinae) insert(size_type index_, column_traits<0>::param_type id, column_traits<1>::param_type name = "", column_traits<2>::param_type pos = {}, - column_traits<3>::param_type orient = { 1, 0, 0, 0 }) // - noexcept(table_traits::insert_is_nothrow) // - SOAGEN_REQUIRES(table_traits::all_move_or_copy_constructible&& table_traits::all_move_or_copy_assignable) // + column_traits<3>::param_type orient = { 1, 0, 0, 0 }) // + noexcept(table_traits::insert_is_nothrow) // { table_.emplace(index_, static_cast::param_forward_type>(id), @@ -649,20 +665,39 @@ namespace soagen::examples return *this; } + /// @brief Inserts a new row at an arbitrary position in the table (rvalue overload). + /// + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = can_insert_rvalues_) // + SOAGEN_CPP20_CONSTEXPR + entities& insert(SOAGEN_ENABLE_IF_T(size_type, sfinae) index_, + column_traits<0>::rvalue_type id, + column_traits<1>::rvalue_type name = "", + column_traits<2>::rvalue_type pos = {}, + column_traits<3>::rvalue_type orient = { 1, 0, 0, 0 }) // + noexcept(table_traits::insert_is_nothrow) // + { + table_.emplace(index_, + static_cast::rvalue_forward_type>(id), + static_cast::rvalue_forward_type>(name), + static_cast::rvalue_forward_type>(pos), + static_cast::rvalue_forward_type>(orient)); + return *this; + } + + // ------ insert(iterator) --------------------------------------------------------------------- + /// @brief Inserts a new row at an arbitrary position in the table. /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - SOAGEN_HIDDEN(template - ) + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = can_insert_) // SOAGEN_CPP20_CONSTEXPR SOAGEN_ENABLE_IF_T(iterator, sfinae) insert(iterator iter_, column_traits<0>::param_type id, column_traits<1>::param_type name = "", column_traits<2>::param_type pos = {}, - column_traits<3>::param_type orient = { 1, 0, 0, 0 }) // - noexcept(table_traits::insert_is_nothrow) // - SOAGEN_REQUIRES(table_traits::all_move_or_copy_constructible&& table_traits::all_move_or_copy_assignable) // + column_traits<3>::param_type orient = { 1, 0, 0, 0 }) // + noexcept(table_traits::insert_is_nothrow) // { table_.emplace(static_cast(iter_), static_cast::param_forward_type>(id), @@ -674,18 +709,15 @@ namespace soagen::examples /// @brief Inserts a new row at an arbitrary position in the table. /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - SOAGEN_HIDDEN(template - ) + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = can_insert_) // SOAGEN_CPP20_CONSTEXPR SOAGEN_ENABLE_IF_T(const_iterator, sfinae) insert(const_iterator iter_, column_traits<0>::param_type id, column_traits<1>::param_type name = "", column_traits<2>::param_type pos = {}, - column_traits<3>::param_type orient = { 1, 0, 0, 0 }) // - noexcept(table_traits::insert_is_nothrow) // - SOAGEN_REQUIRES(table_traits::all_move_or_copy_constructible&& table_traits::all_move_or_copy_assignable) // + column_traits<3>::param_type orient = { 1, 0, 0, 0 }) // + noexcept(table_traits::insert_is_nothrow) // { table_.emplace(static_cast(iter_), static_cast::param_forward_type>(id), @@ -697,45 +729,15 @@ namespace soagen::examples /// @brief Inserts a new row at an arbitrary position in the table (rvalue overload). /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - SOAGEN_HIDDEN( - template - ) - SOAGEN_CPP20_CONSTEXPR - entities& insert(SOAGEN_ENABLE_IF_T(size_type, sfinae) index_, - column_traits<0>::rvalue_type id, - column_traits<1>::rvalue_type name = "", - column_traits<2>::rvalue_type pos = {}, - column_traits<3>::rvalue_type orient = { 1, 0, 0, 0 }) // - noexcept(table_traits::rvalue_insert_is_nothrow) // - SOAGEN_REQUIRES(table_traits::rvalues_are_distinct&& table_traits::all_move_or_copy_constructible&& - table_traits::all_move_or_copy_assignable) // - { - table_.emplace(index_, - static_cast::rvalue_forward_type>(id), - static_cast::rvalue_forward_type>(name), - static_cast::rvalue_forward_type>(pos), - static_cast::rvalue_forward_type>(orient)); - return *this; - } - - /// @brief Inserts a new row at an arbitrary position in the table (rvalue overload). - /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - SOAGEN_HIDDEN( - template - ) + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = can_insert_rvalues_) // SOAGEN_CPP20_CONSTEXPR iterator insert(SOAGEN_ENABLE_IF_T(iterator, sfinae) iter_, column_traits<0>::rvalue_type id, column_traits<1>::rvalue_type name = "", column_traits<2>::rvalue_type pos = {}, column_traits<3>::rvalue_type orient = { 1, 0, 0, 0 }) // - noexcept(table_traits::rvalue_insert_is_nothrow) // - SOAGEN_REQUIRES(table_traits::rvalues_are_distinct&& table_traits::all_move_or_copy_constructible&& - table_traits::all_move_or_copy_assignable) // + noexcept(table_traits::insert_is_nothrow) // { table_.emplace(static_cast(iter_), static_cast::rvalue_forward_type>(id), @@ -747,20 +749,15 @@ namespace soagen::examples /// @brief Inserts a new row at an arbitrary position in the table (rvalue overload). /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - SOAGEN_HIDDEN( - template - ) + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = can_insert_rvalues_) // SOAGEN_CPP20_CONSTEXPR const_iterator insert(SOAGEN_ENABLE_IF_T(const_iterator, sfinae) iter_, column_traits<0>::rvalue_type id, column_traits<1>::rvalue_type name = "", column_traits<2>::rvalue_type pos = {}, column_traits<3>::rvalue_type orient = { 1, 0, 0, 0 }) // - noexcept(table_traits::rvalue_insert_is_nothrow) // - SOAGEN_REQUIRES(table_traits::rvalues_are_distinct&& table_traits::all_move_or_copy_constructible&& - table_traits::all_move_or_copy_assignable) // + noexcept(table_traits::insert_is_nothrow) // { table_.emplace(static_cast(iter_), static_cast::rvalue_forward_type>(id), @@ -770,24 +767,25 @@ namespace soagen::examples return iter_; } + // ------ emplace(size_type) ------------------------------------------------------------------- + /// @brief Constructs a new row directly in-place at an arbitrary position in the table. /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - template ::default_emplace_type, - typename Pos = column_traits<2>::default_emplace_type, - typename Orient = column_traits<3>::default_emplace_type SOAGEN_ENABLE_IF( - (table_traits::all_move_or_copy_constructible && table_traits::all_move_or_copy_assignable - && table_traits::row_constructible_from))> + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_CONSTRAINED_TEMPLATE( + sfinae, + typename Id, + typename Name = column_traits<1>::default_emplace_type, + typename Pos = column_traits<2>::default_emplace_type, + typename Orient = column_traits<3>::default_emplace_type SOAGEN_HIDDEN_PARAM( + bool sfinae = table_traits::row_constructible_from && can_insert_)) // SOAGEN_CPP20_CONSTEXPR - entities& emplace(size_type index_, - Id&& id, - Name&& name = "", - Pos&& pos = {}, - Orient&& orient = { 1, 0, 0, 0 }) // + SOAGEN_ENABLE_IF_T(entities&, sfinae) emplace(size_type index_, + Id&& id, + Name&& name = "", + Pos&& pos = {}, + Orient&& orient = { 1, 0, 0, 0 }) // noexcept(table_traits::emplace_is_nothrow) // - SOAGEN_REQUIRES(table_traits::all_move_or_copy_constructible&& table_traits::all_move_or_copy_assignable&& - table_traits::row_constructible_from) // { table_.emplace(index_, static_cast(id), @@ -797,47 +795,39 @@ namespace soagen::examples return *this; } - /// @brief Constructs a new row directly in-place at an arbitrary position in the table. + /// @brief Constructs a new row directly in-place at an arbitrary position in the table by unpacking a tuple-like object. /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - template ::default_emplace_type, - typename Pos = column_traits<2>::default_emplace_type, - typename Orient = column_traits<3>::default_emplace_type SOAGEN_ENABLE_IF( - (table_traits::all_move_or_copy_constructible && table_traits::all_move_or_copy_assignable - && table_traits::row_constructible_from))> + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_CONSTRAINED_TEMPLATE(sfinae, + typename Tuple SOAGEN_HIDDEN_PARAM( + bool sfinae = table_traits::row_constructible_from && can_insert_)) // SOAGEN_CPP20_CONSTEXPR - iterator emplace(iterator iter_, Id&& id, Name&& name = "", Pos&& pos = {}, Orient&& orient = { 1, 0, 0, 0 }) // - noexcept(table_traits::emplace_is_nothrow) // - SOAGEN_REQUIRES(table_traits::all_move_or_copy_constructible&& table_traits::all_move_or_copy_assignable&& - table_traits::row_constructible_from) // + entities& emplace(SOAGEN_ENABLE_IF_T(size_type, sfinae) index_, Tuple&& tuple_) // + noexcept(table_traits::emplace_is_nothrow) // { - table_.emplace(static_cast(iter_), - static_cast(id), - static_cast(name), - static_cast(pos), - static_cast(orient)); - return iter_; + table_.emplace(index_, static_cast(tuple_)); + return *this; } + // ------ emplace(iterator) -------------------------------------------------------------------- + /// @brief Constructs a new row directly in-place at an arbitrary position in the table. /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - template ::default_emplace_type, - typename Pos = column_traits<2>::default_emplace_type, - typename Orient = column_traits<3>::default_emplace_type SOAGEN_ENABLE_IF( - (table_traits::all_move_or_copy_constructible && table_traits::all_move_or_copy_assignable - && table_traits::row_constructible_from))> + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_CONSTRAINED_TEMPLATE( + sfinae, + typename Id, + typename Name = column_traits<1>::default_emplace_type, + typename Pos = column_traits<2>::default_emplace_type, + typename Orient = column_traits<3>::default_emplace_type SOAGEN_HIDDEN_PARAM( + bool sfinae = table_traits::row_constructible_from && can_insert_)) // SOAGEN_CPP20_CONSTEXPR - const_iterator emplace(const_iterator iter_, - Id&& id, - Name&& name = "", - Pos&& pos = {}, - Orient&& orient = { 1, 0, 0, 0 }) // + SOAGEN_ENABLE_IF_T(iterator, sfinae) emplace(iterator iter_, + Id&& id, + Name&& name = "", + Pos&& pos = {}, + Orient&& orient = { 1, 0, 0, 0 }) // noexcept(table_traits::emplace_is_nothrow) // - SOAGEN_REQUIRES(table_traits::all_move_or_copy_constructible&& table_traits::all_move_or_copy_assignable&& - table_traits::row_constructible_from) // { table_.emplace(static_cast(iter_), static_cast(id), @@ -849,50 +839,53 @@ namespace soagen::examples /// @brief Constructs a new row directly in-place at an arbitrary position in the table by unpacking a tuple-like object. /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - template - && table_traits::all_move_or_copy_constructible - && table_traits::all_move_or_copy_assignable))> + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_CONSTRAINED_TEMPLATE(sfinae, + typename Tuple SOAGEN_HIDDEN_PARAM( + bool sfinae = table_traits::row_constructible_from && can_insert_)) // SOAGEN_CPP20_CONSTEXPR - entities& emplace(size_type index_, Tuple&& tuple_) // - noexcept(table_traits::emplace_is_nothrow) // - SOAGEN_REQUIRES( - table_traits::row_constructible_from&& table_traits::all_move_or_copy_constructible&& - table_traits::all_move_or_copy_assignable) // + iterator emplace(SOAGEN_ENABLE_IF_T(iterator, sfinae) iter_, Tuple&& tuple_) // + noexcept(table_traits::emplace_is_nothrow) // { - table_.emplace(index_, static_cast(tuple_)); - return *this; + table_.emplace(static_cast(iter_), static_cast(tuple_)); + return iter_; } - /// @brief Constructs a new row directly in-place at an arbitrary position in the table by unpacking a tuple-like object. + /// @brief Constructs a new row directly in-place at an arbitrary position in the table. /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - template - && table_traits::all_move_or_copy_constructible - && table_traits::all_move_or_copy_assignable))> + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_CONSTRAINED_TEMPLATE( + sfinae, + typename Id, + typename Name = column_traits<1>::default_emplace_type, + typename Pos = column_traits<2>::default_emplace_type, + typename Orient = column_traits<3>::default_emplace_type SOAGEN_HIDDEN_PARAM( + bool sfinae = table_traits::row_constructible_from && can_insert_)) // SOAGEN_CPP20_CONSTEXPR - iterator emplace(iterator iter_, Tuple&& tuple_) // - noexcept(table_traits::emplace_is_nothrow) // - SOAGEN_REQUIRES( - table_traits::row_constructible_from&& table_traits::all_move_or_copy_constructible&& - table_traits::all_move_or_copy_assignable) // + SOAGEN_ENABLE_IF_T(const_iterator, sfinae) emplace(const_iterator iter_, + Id&& id, + Name&& name = "", + Pos&& pos = {}, + Orient&& orient = { 1, 0, 0, 0 }) // + noexcept(table_traits::emplace_is_nothrow) // { - table_.emplace(static_cast(iter_), static_cast(tuple_)); + table_.emplace(static_cast(iter_), + static_cast(id), + static_cast(name), + static_cast(pos), + static_cast(orient)); return iter_; } /// @brief Constructs a new row directly in-place at an arbitrary position in the table by unpacking a tuple-like object. /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - template - && table_traits::all_move_or_copy_constructible - && table_traits::all_move_or_copy_assignable))> + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_CONSTRAINED_TEMPLATE(sfinae, + typename Tuple SOAGEN_HIDDEN_PARAM( + bool sfinae = table_traits::row_constructible_from && can_insert_)) // SOAGEN_CPP20_CONSTEXPR - const_iterator emplace(const_iterator iter_, Tuple&& tuple_) // - noexcept(table_traits::emplace_is_nothrow) // - SOAGEN_REQUIRES( - table_traits::row_constructible_from&& table_traits::all_move_or_copy_constructible&& - table_traits::all_move_or_copy_assignable) // + const_iterator emplace(SOAGEN_ENABLE_IF_T(const_iterator, sfinae) iter_, Tuple&& tuple_) // + noexcept(table_traits::emplace_is_nothrow) // { table_.emplace(static_cast(iter_), static_cast(tuple_)); return iter_; diff --git a/examples/shapes.hpp b/examples/shapes.hpp index 10d9f2e..1a8100d 100644 --- a/examples/shapes.hpp +++ b/examples/shapes.hpp @@ -41,6 +41,9 @@ SOAGEN_DISABLE_SPAM_WARNINGS; #if defined(DOXYGEN) || defined(__DOXYGEN) || defined(__DOXYGEN__) || defined(__doxygen__) || defined(__POXY__) \ || defined(__poxy__) + #ifndef SOAGEN_CONSTRAINED_TEMPLATE + #define SOAGEN_CONSTRAINED_TEMPLATE(cond, ...) template <__VA_ARGS__> + #endif #ifndef SOAGEN_DOXYGEN #define SOAGEN_DOXYGEN 1 #endif @@ -329,11 +332,13 @@ namespace soagen::examples /// @brief Gets the soagen::column_traits for a specific column of the table. template - using column_traits = typename table_traits::template column(Column)>; + using column_traits = + POXY_IMPLEMENTATION_DETAIL(typename table_traits::template column(Column)>); /// @brief Gets the type of a specific column in the table. template - using column_type = typename column_traits(Column)>::value_type; + using column_type = + POXY_IMPLEMENTATION_DETAIL(typename column_traits(Column)>::value_type); /// @brief Row iterators returned by iterator functions. using iterator = soagen::iterator_type; @@ -496,11 +501,11 @@ namespace soagen::examples /// @brief Erases the row at the given position. /// /// @availability This method is only available when all the column types are move-assignable. - SOAGEN_HIDDEN(template >) + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = soagen::has_erase_member) SOAGEN_ALWAYS_INLINE - SOAGEN_CPP20_CONSTEXPR // - SOAGEN_ENABLE_IF_T(boxes&, sfinae) erase(size_type pos) // - noexcept(soagen::has_nothrow_erase_member) + SOAGEN_CPP20_CONSTEXPR // + SOAGEN_ENABLE_IF_T(boxes&, sfinae) erase(size_type pos) // + noexcept(soagen::has_nothrow_erase_member) // { table_.erase(pos); return *this; @@ -518,11 +523,11 @@ namespace soagen::examples /// @returns The position of the row that was moved into the erased row's position, if any. /// /// @availability This method is only available when all the column types are move-assignable. - SOAGEN_HIDDEN(template >) + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = soagen::has_unordered_erase_member) SOAGEN_ALWAYS_INLINE SOAGEN_CPP20_CONSTEXPR // SOAGEN_ENABLE_IF_T(soagen::optional, sfinae) unordered_erase(size_type pos) // - noexcept(soagen::has_nothrow_unordered_erase_member) + noexcept(soagen::has_nothrow_unordered_erase_member) // { return table_.unordered_erase(pos); } @@ -533,11 +538,11 @@ namespace soagen::examples /// or #end() if the one removed was the last row in the table. /// /// @availability This method is only available when all the column types are move-assignable. - SOAGEN_HIDDEN(template >) + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = soagen::has_erase_member) SOAGEN_ALWAYS_INLINE SOAGEN_CPP20_CONSTEXPR - SOAGEN_ENABLE_IF_T(iterator, sfinae) erase(iterator pos) // - noexcept(soagen::has_nothrow_erase_member) + SOAGEN_ENABLE_IF_T(iterator, sfinae) erase(iterator pos) // + noexcept(soagen::has_nothrow_erase_member) // { table_.erase(static_cast(pos)); return pos; @@ -555,11 +560,11 @@ namespace soagen::examples /// @returns The position of the row that was moved into the erased row's position, if any. /// /// @availability This method is only available when all the column types are move-assignable. - SOAGEN_HIDDEN(template >) + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = soagen::has_unordered_erase_member) SOAGEN_ALWAYS_INLINE SOAGEN_CPP20_CONSTEXPR SOAGEN_ENABLE_IF_T(soagen::optional, sfinae) unordered_erase(iterator pos) // - noexcept(soagen::has_nothrow_unordered_erase_member) + noexcept(soagen::has_nothrow_unordered_erase_member) // { if (auto moved_pos = table_.unordered_erase(static_cast(pos)); moved_pos) return iterator{ *this, static_cast(*moved_pos) }; @@ -572,11 +577,11 @@ namespace soagen::examples /// or #cend() if the one removed was the last row in the table. /// /// @availability This method is only available when all the column types are move-assignable. - SOAGEN_HIDDEN(template >) + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = soagen::has_erase_member) SOAGEN_ALWAYS_INLINE SOAGEN_CPP20_CONSTEXPR SOAGEN_ENABLE_IF_T(const_iterator, sfinae) erase(const_iterator pos) // - noexcept(soagen::has_nothrow_erase_member) + noexcept(soagen::has_nothrow_erase_member) // { table_.erase(static_cast(pos)); return pos; @@ -594,11 +599,11 @@ namespace soagen::examples /// @returns The position of the row that was moved into the erased row's position, if any. /// /// @availability This method is only available when all the column types are move-assignable. - SOAGEN_HIDDEN(template >) + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = soagen::has_unordered_erase_member) SOAGEN_ALWAYS_INLINE SOAGEN_CPP20_CONSTEXPR SOAGEN_ENABLE_IF_T(soagen::optional, sfinae) unordered_erase(const_iterator pos) // - noexcept(soagen::has_nothrow_unordered_erase_member) + noexcept(soagen::has_nothrow_unordered_erase_member) // { if (auto moved_pos = table_.unordered_erase(static_cast(pos)); moved_pos) return const_iterator{ *this, static_cast(*moved_pos) }; @@ -646,6 +651,8 @@ namespace soagen::examples /// @name Adding rows /// @{ + // ------ push_back() -------------------------------------------------------------------------- + /// @brief Adds a new row at the end of the table. SOAGEN_CPP20_CONSTEXPR boxes& push_back(column_traits<0>::param_type center_x, @@ -668,9 +675,9 @@ namespace soagen::examples } /// @brief Adds a new row at the end of the table (rvalue overload). - SOAGEN_HIDDEN(template ) + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = table_traits::rvalues_are_distinct) SOAGEN_CPP20_CONSTEXPR - boxes& push_back(SOAGEN_ENABLE_IF_T(column_traits<0>::rvalue_type, sfinae) center_x, + boxes& push_back(column_traits<0>::rvalue_type center_x, column_traits<1>::rvalue_type center_y, column_traits<2>::rvalue_type center_z, column_traits<3>::rvalue_type extents_x = 0.5, @@ -678,7 +685,6 @@ namespace soagen::examples column_traits<5>::rvalue_type extents_z = 0.5, column_traits<6>::rvalue_type mass = default_mass) // noexcept(table_traits::rvalue_push_back_is_nothrow) // - SOAGEN_REQUIRES(table_traits::rvalues_are_distinct) // { table_.emplace_back(static_cast::rvalue_forward_type>(center_x), static_cast::rvalue_forward_type>(center_y), @@ -690,21 +696,23 @@ namespace soagen::examples return *this; } + // ------ emplace_back() ----------------------------------------------------------------------- + /// @brief Constructs a new row directly in-place at the end of the table. - template ::default_emplace_type, - typename ExtentsY = column_traits<4>::default_emplace_type, - typename ExtentsZ = column_traits<5>::default_emplace_type, - typename Mass = column_traits<6>::default_emplace_type SOAGEN_ENABLE_IF( - table_traits::row_constructible_from)> + SOAGEN_CONSTRAINED_TEMPLATE((table_traits::row_constructible_from), // + typename CenterX, + typename CenterY, + typename CenterZ, + typename ExtentsX = column_traits<3>::default_emplace_type, + typename ExtentsY = column_traits<4>::default_emplace_type, + typename ExtentsZ = column_traits<5>::default_emplace_type, + typename Mass = column_traits<6>::default_emplace_type) // SOAGEN_CPP20_CONSTEXPR boxes& emplace_back(CenterX&& center_x, CenterY&& center_y, @@ -721,13 +729,6 @@ namespace soagen::examples ExtentsY&&, ExtentsZ&&, Mass&&>) // - SOAGEN_REQUIRES(table_traits::row_constructible_from) // { table_.emplace_back(static_cast(center_x), static_cast(center_y), @@ -740,11 +741,10 @@ namespace soagen::examples } /// @brief Constructs a new row directly in-place at the end of the table by unpacking a tuple-like object. - template )> + SOAGEN_CONSTRAINED_TEMPLATE(table_traits::row_constructible_from, typename Tuple) SOAGEN_CPP20_CONSTEXPR boxes& emplace_back(Tuple&& tuple_) // noexcept(table_traits::emplace_back_is_nothrow) // - SOAGEN_REQUIRES(table_traits::row_constructible_from) // { table_.emplace_back(static_cast(tuple_)); return *this; @@ -753,15 +753,26 @@ namespace soagen::examples /// @} /// @name Inserting rows - /// @availability These overloads are only available when all the column types are move-constructible and move-assignable. + /// @availability These overloads are only available when all the column types are move/copy-constructible and move/copy-assignable. /// @{ + private: + /// @cond + + static constexpr bool can_insert_ = + table_traits::all_move_or_copy_constructible && table_traits::all_move_or_copy_assignable; + + static constexpr bool can_insert_rvalues_ = can_insert_ && table_traits::rvalues_are_distinct; + + /// @endcond + + public: + // ------ insert(size_type) -------------------------------------------------------------------- + /// @brief Inserts a new row at an arbitrary position in the table. /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - SOAGEN_HIDDEN(template - ) + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = can_insert_) // SOAGEN_CPP20_CONSTEXPR SOAGEN_ENABLE_IF_T(boxes&, sfinae) insert(size_type index_, column_traits<0>::param_type center_x, @@ -770,9 +781,8 @@ namespace soagen::examples column_traits<3>::param_type extents_x = 0.5, column_traits<4>::param_type extents_y = 0.5, column_traits<5>::param_type extents_z = 0.5, - column_traits<6>::param_type mass = default_mass) // - noexcept(table_traits::insert_is_nothrow) // - SOAGEN_REQUIRES(table_traits::all_move_or_copy_constructible&& table_traits::all_move_or_copy_assignable) // + column_traits<6>::param_type mass = default_mass) // + noexcept(table_traits::insert_is_nothrow) // { table_.emplace(index_, static_cast::param_forward_type>(center_x), @@ -785,12 +795,38 @@ namespace soagen::examples return *this; } + /// @brief Inserts a new row at an arbitrary position in the table (rvalue overload). + /// + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = can_insert_rvalues_) // + SOAGEN_CPP20_CONSTEXPR + boxes& insert(SOAGEN_ENABLE_IF_T(size_type, sfinae) index_, + column_traits<0>::rvalue_type center_x, + column_traits<1>::rvalue_type center_y, + column_traits<2>::rvalue_type center_z, + column_traits<3>::rvalue_type extents_x = 0.5, + column_traits<4>::rvalue_type extents_y = 0.5, + column_traits<5>::rvalue_type extents_z = 0.5, + column_traits<6>::rvalue_type mass = default_mass) // + noexcept(table_traits::insert_is_nothrow) // + { + table_.emplace(index_, + static_cast::rvalue_forward_type>(center_x), + static_cast::rvalue_forward_type>(center_y), + static_cast::rvalue_forward_type>(center_z), + static_cast::rvalue_forward_type>(extents_x), + static_cast::rvalue_forward_type>(extents_y), + static_cast::rvalue_forward_type>(extents_z), + static_cast::rvalue_forward_type>(mass)); + return *this; + } + + // ------ insert(iterator) --------------------------------------------------------------------- + /// @brief Inserts a new row at an arbitrary position in the table. /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - SOAGEN_HIDDEN(template - ) + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = can_insert_) // SOAGEN_CPP20_CONSTEXPR SOAGEN_ENABLE_IF_T(iterator, sfinae) insert(iterator iter_, column_traits<0>::param_type center_x, @@ -799,9 +835,8 @@ namespace soagen::examples column_traits<3>::param_type extents_x = 0.5, column_traits<4>::param_type extents_y = 0.5, column_traits<5>::param_type extents_z = 0.5, - column_traits<6>::param_type mass = default_mass) // - noexcept(table_traits::insert_is_nothrow) // - SOAGEN_REQUIRES(table_traits::all_move_or_copy_constructible&& table_traits::all_move_or_copy_assignable) // + column_traits<6>::param_type mass = default_mass) // + noexcept(table_traits::insert_is_nothrow) // { table_.emplace(static_cast(iter_), static_cast::param_forward_type>(center_x), @@ -816,10 +851,8 @@ namespace soagen::examples /// @brief Inserts a new row at an arbitrary position in the table. /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - SOAGEN_HIDDEN(template - ) + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = can_insert_) // SOAGEN_CPP20_CONSTEXPR SOAGEN_ENABLE_IF_T(const_iterator, sfinae) insert(const_iterator iter_, column_traits<0>::param_type center_x, @@ -828,9 +861,8 @@ namespace soagen::examples column_traits<3>::param_type extents_x = 0.5, column_traits<4>::param_type extents_y = 0.5, column_traits<5>::param_type extents_z = 0.5, - column_traits<6>::param_type mass = default_mass) // - noexcept(table_traits::insert_is_nothrow) // - SOAGEN_REQUIRES(table_traits::all_move_or_copy_constructible&& table_traits::all_move_or_copy_assignable) // + column_traits<6>::param_type mass = default_mass) // + noexcept(table_traits::insert_is_nothrow) // { table_.emplace(static_cast(iter_), static_cast::param_forward_type>(center_x), @@ -845,42 +877,8 @@ namespace soagen::examples /// @brief Inserts a new row at an arbitrary position in the table (rvalue overload). /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - SOAGEN_HIDDEN( - template - ) - SOAGEN_CPP20_CONSTEXPR - boxes& insert(SOAGEN_ENABLE_IF_T(size_type, sfinae) index_, - column_traits<0>::rvalue_type center_x, - column_traits<1>::rvalue_type center_y, - column_traits<2>::rvalue_type center_z, - column_traits<3>::rvalue_type extents_x = 0.5, - column_traits<4>::rvalue_type extents_y = 0.5, - column_traits<5>::rvalue_type extents_z = 0.5, - column_traits<6>::rvalue_type mass = default_mass) // - noexcept(table_traits::rvalue_insert_is_nothrow) // - SOAGEN_REQUIRES(table_traits::rvalues_are_distinct&& table_traits::all_move_or_copy_constructible&& - table_traits::all_move_or_copy_assignable) // - { - table_.emplace(index_, - static_cast::rvalue_forward_type>(center_x), - static_cast::rvalue_forward_type>(center_y), - static_cast::rvalue_forward_type>(center_z), - static_cast::rvalue_forward_type>(extents_x), - static_cast::rvalue_forward_type>(extents_y), - static_cast::rvalue_forward_type>(extents_z), - static_cast::rvalue_forward_type>(mass)); - return *this; - } - - /// @brief Inserts a new row at an arbitrary position in the table (rvalue overload). - /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - SOAGEN_HIDDEN( - template - ) + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = can_insert_rvalues_) // SOAGEN_CPP20_CONSTEXPR iterator insert(SOAGEN_ENABLE_IF_T(iterator, sfinae) iter_, column_traits<0>::rvalue_type center_x, @@ -890,9 +888,7 @@ namespace soagen::examples column_traits<4>::rvalue_type extents_y = 0.5, column_traits<5>::rvalue_type extents_z = 0.5, column_traits<6>::rvalue_type mass = default_mass) // - noexcept(table_traits::rvalue_insert_is_nothrow) // - SOAGEN_REQUIRES(table_traits::rvalues_are_distinct&& table_traits::all_move_or_copy_constructible&& - table_traits::all_move_or_copy_assignable) // + noexcept(table_traits::insert_is_nothrow) // { table_.emplace(static_cast(iter_), static_cast::rvalue_forward_type>(center_x), @@ -907,11 +903,8 @@ namespace soagen::examples /// @brief Inserts a new row at an arbitrary position in the table (rvalue overload). /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - SOAGEN_HIDDEN( - template - ) + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = can_insert_rvalues_) // SOAGEN_CPP20_CONSTEXPR const_iterator insert(SOAGEN_ENABLE_IF_T(const_iterator, sfinae) iter_, column_traits<0>::rvalue_type center_x, @@ -921,9 +914,7 @@ namespace soagen::examples column_traits<4>::rvalue_type extents_y = 0.5, column_traits<5>::rvalue_type extents_z = 0.5, column_traits<6>::rvalue_type mass = default_mass) // - noexcept(table_traits::rvalue_insert_is_nothrow) // - SOAGEN_REQUIRES(table_traits::rvalues_are_distinct&& table_traits::all_move_or_copy_constructible&& - table_traits::all_move_or_copy_assignable) // + noexcept(table_traits::insert_is_nothrow) // { table_.emplace(static_cast(iter_), static_cast::rvalue_forward_type>(center_x), @@ -936,33 +927,36 @@ namespace soagen::examples return iter_; } + // ------ emplace(size_type) ------------------------------------------------------------------- + /// @brief Constructs a new row directly in-place at an arbitrary position in the table. /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - template ::default_emplace_type, - typename ExtentsY = column_traits<4>::default_emplace_type, - typename ExtentsZ = column_traits<5>::default_emplace_type, - typename Mass = column_traits<6>::default_emplace_type SOAGEN_ENABLE_IF( - (table_traits::all_move_or_copy_constructible && table_traits::all_move_or_copy_assignable - && table_traits::row_constructible_from))> + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_CONSTRAINED_TEMPLATE(sfinae, + typename CenterX, + typename CenterY, + typename CenterZ, + typename ExtentsX = column_traits<3>::default_emplace_type, + typename ExtentsY = column_traits<4>::default_emplace_type, + typename ExtentsZ = column_traits<5>::default_emplace_type, + typename Mass = column_traits<6>::default_emplace_type SOAGEN_HIDDEN_PARAM( + bool sfinae = table_traits::row_constructible_from + && can_insert_)) // SOAGEN_CPP20_CONSTEXPR - boxes& emplace(size_type index_, - CenterX&& center_x, - CenterY&& center_y, - CenterZ&& center_z, - ExtentsX&& extents_x = 0.5, - ExtentsY&& extents_y = 0.5, - ExtentsZ&& extents_z = 0.5, - Mass&& mass = default_mass) // + SOAGEN_ENABLE_IF_T(boxes&, sfinae) emplace(size_type index_, + CenterX&& center_x, + CenterY&& center_y, + CenterZ&& center_z, + ExtentsX&& extents_x = 0.5, + ExtentsY&& extents_y = 0.5, + ExtentsZ&& extents_z = 0.5, + Mass&& mass = default_mass) // noexcept(table_traits::emplace_is_nothrow) // - SOAGEN_REQUIRES(table_traits::all_move_or_copy_constructible&& table_traits::all_move_or_copy_assignable&& - table_traits::row_constructible_from) // { table_.emplace(index_, static_cast(center_x), @@ -991,33 +977,50 @@ namespace soagen::examples return *this; } + /// @brief Constructs a new row directly in-place at an arbitrary position in the table by unpacking a tuple-like object. + /// + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_CONSTRAINED_TEMPLATE(sfinae, + typename Tuple SOAGEN_HIDDEN_PARAM( + bool sfinae = table_traits::row_constructible_from && can_insert_)) // + SOAGEN_CPP20_CONSTEXPR + boxes& emplace(SOAGEN_ENABLE_IF_T(size_type, sfinae) index_, Tuple&& tuple_) // + noexcept(table_traits::emplace_is_nothrow) // + { + table_.emplace(index_, static_cast(tuple_)); + return *this; + } + + // ------ emplace(iterator) -------------------------------------------------------------------- + /// @brief Constructs a new row directly in-place at an arbitrary position in the table. /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - template ::default_emplace_type, - typename ExtentsY = column_traits<4>::default_emplace_type, - typename ExtentsZ = column_traits<5>::default_emplace_type, - typename Mass = column_traits<6>::default_emplace_type SOAGEN_ENABLE_IF( - (table_traits::all_move_or_copy_constructible && table_traits::all_move_or_copy_assignable - && table_traits::row_constructible_from))> + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_CONSTRAINED_TEMPLATE(sfinae, + typename CenterX, + typename CenterY, + typename CenterZ, + typename ExtentsX = column_traits<3>::default_emplace_type, + typename ExtentsY = column_traits<4>::default_emplace_type, + typename ExtentsZ = column_traits<5>::default_emplace_type, + typename Mass = column_traits<6>::default_emplace_type SOAGEN_HIDDEN_PARAM( + bool sfinae = table_traits::row_constructible_from + && can_insert_)) // SOAGEN_CPP20_CONSTEXPR - iterator emplace(iterator iter_, - CenterX&& center_x, - CenterY&& center_y, - CenterZ&& center_z, - ExtentsX&& extents_x = 0.5, - ExtentsY&& extents_y = 0.5, - ExtentsZ&& extents_z = 0.5, - Mass&& mass = default_mass) // + SOAGEN_ENABLE_IF_T(iterator, sfinae) emplace(iterator iter_, + CenterX&& center_x, + CenterY&& center_y, + CenterZ&& center_z, + ExtentsX&& extents_x = 0.5, + ExtentsY&& extents_y = 0.5, + ExtentsZ&& extents_z = 0.5, + Mass&& mass = default_mass) // noexcept(table_traits::emplace_is_nothrow) // - SOAGEN_REQUIRES(table_traits::all_move_or_copy_constructible&& table_traits::all_move_or_copy_assignable&& - table_traits::row_constructible_from) // { table_.emplace(static_cast(iter_), static_cast(center_x), @@ -1046,33 +1041,48 @@ namespace soagen::examples return iter_; } + /// @brief Constructs a new row directly in-place at an arbitrary position in the table by unpacking a tuple-like object. + /// + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_CONSTRAINED_TEMPLATE(sfinae, + typename Tuple SOAGEN_HIDDEN_PARAM( + bool sfinae = table_traits::row_constructible_from && can_insert_)) // + SOAGEN_CPP20_CONSTEXPR + iterator emplace(SOAGEN_ENABLE_IF_T(iterator, sfinae) iter_, Tuple&& tuple_) // + noexcept(table_traits::emplace_is_nothrow) // + { + table_.emplace(static_cast(iter_), static_cast(tuple_)); + return iter_; + } + /// @brief Constructs a new row directly in-place at an arbitrary position in the table. /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - template ::default_emplace_type, - typename ExtentsY = column_traits<4>::default_emplace_type, - typename ExtentsZ = column_traits<5>::default_emplace_type, - typename Mass = column_traits<6>::default_emplace_type SOAGEN_ENABLE_IF( - (table_traits::all_move_or_copy_constructible && table_traits::all_move_or_copy_assignable - && table_traits::row_constructible_from))> + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_CONSTRAINED_TEMPLATE(sfinae, + typename CenterX, + typename CenterY, + typename CenterZ, + typename ExtentsX = column_traits<3>::default_emplace_type, + typename ExtentsY = column_traits<4>::default_emplace_type, + typename ExtentsZ = column_traits<5>::default_emplace_type, + typename Mass = column_traits<6>::default_emplace_type SOAGEN_HIDDEN_PARAM( + bool sfinae = table_traits::row_constructible_from + && can_insert_)) // SOAGEN_CPP20_CONSTEXPR - const_iterator emplace(const_iterator iter_, - CenterX&& center_x, - CenterY&& center_y, - CenterZ&& center_z, - ExtentsX&& extents_x = 0.5, - ExtentsY&& extents_y = 0.5, - ExtentsZ&& extents_z = 0.5, - Mass&& mass = default_mass) // + SOAGEN_ENABLE_IF_T(const_iterator, sfinae) emplace(const_iterator iter_, + CenterX&& center_x, + CenterY&& center_y, + CenterZ&& center_z, + ExtentsX&& extents_x = 0.5, + ExtentsY&& extents_y = 0.5, + ExtentsZ&& extents_z = 0.5, + Mass&& mass = default_mass) // noexcept(table_traits::emplace_is_nothrow) // - SOAGEN_REQUIRES(table_traits::all_move_or_copy_constructible&& table_traits::all_move_or_copy_assignable&& - table_traits::row_constructible_from) // { table_.emplace(static_cast(iter_), static_cast(center_x), @@ -1103,50 +1105,13 @@ namespace soagen::examples /// @brief Constructs a new row directly in-place at an arbitrary position in the table by unpacking a tuple-like object. /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - template - && table_traits::all_move_or_copy_constructible - && table_traits::all_move_or_copy_assignable))> - SOAGEN_CPP20_CONSTEXPR - boxes& emplace(size_type index_, Tuple&& tuple_) // - noexcept(table_traits::emplace_is_nothrow) // - SOAGEN_REQUIRES( - table_traits::row_constructible_from&& table_traits::all_move_or_copy_constructible&& - table_traits::all_move_or_copy_assignable) // - { - table_.emplace(index_, static_cast(tuple_)); - return *this; - } - - /// @brief Constructs a new row directly in-place at an arbitrary position in the table by unpacking a tuple-like object. - /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - template - && table_traits::all_move_or_copy_constructible - && table_traits::all_move_or_copy_assignable))> - SOAGEN_CPP20_CONSTEXPR - iterator emplace(iterator iter_, Tuple&& tuple_) // - noexcept(table_traits::emplace_is_nothrow) // - SOAGEN_REQUIRES( - table_traits::row_constructible_from&& table_traits::all_move_or_copy_constructible&& - table_traits::all_move_or_copy_assignable) // - { - table_.emplace(static_cast(iter_), static_cast(tuple_)); - return iter_; - } - - /// @brief Constructs a new row directly in-place at an arbitrary position in the table by unpacking a tuple-like object. - /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - template - && table_traits::all_move_or_copy_constructible - && table_traits::all_move_or_copy_assignable))> + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_CONSTRAINED_TEMPLATE(sfinae, + typename Tuple SOAGEN_HIDDEN_PARAM( + bool sfinae = table_traits::row_constructible_from && can_insert_)) // SOAGEN_CPP20_CONSTEXPR - const_iterator emplace(const_iterator iter_, Tuple&& tuple_) // - noexcept(table_traits::emplace_is_nothrow) // - SOAGEN_REQUIRES( - table_traits::row_constructible_from&& table_traits::all_move_or_copy_constructible&& - table_traits::all_move_or_copy_assignable) // + const_iterator emplace(SOAGEN_ENABLE_IF_T(const_iterator, sfinae) iter_, Tuple&& tuple_) // + noexcept(table_traits::emplace_is_nothrow) // { table_.emplace(static_cast(iter_), static_cast(tuple_)); return iter_; @@ -1541,11 +1506,13 @@ namespace soagen::examples /// @brief Gets the soagen::column_traits for a specific column of the table. template - using column_traits = typename table_traits::template column(Column)>; + using column_traits = + POXY_IMPLEMENTATION_DETAIL(typename table_traits::template column(Column)>); /// @brief Gets the type of a specific column in the table. template - using column_type = typename column_traits(Column)>::value_type; + using column_type = + POXY_IMPLEMENTATION_DETAIL(typename column_traits(Column)>::value_type); /// @brief Row iterators returned by iterator functions. using iterator = soagen::iterator_type; @@ -1707,11 +1674,11 @@ namespace soagen::examples /// @brief Erases the row at the given position. /// /// @availability This method is only available when all the column types are move-assignable. - SOAGEN_HIDDEN(template >) + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = soagen::has_erase_member) SOAGEN_ALWAYS_INLINE - SOAGEN_CPP20_CONSTEXPR // - SOAGEN_ENABLE_IF_T(spheres&, sfinae) erase(size_type pos) // - noexcept(soagen::has_nothrow_erase_member) + SOAGEN_CPP20_CONSTEXPR // + SOAGEN_ENABLE_IF_T(spheres&, sfinae) erase(size_type pos) // + noexcept(soagen::has_nothrow_erase_member) // { table_.erase(pos); return *this; @@ -1729,11 +1696,11 @@ namespace soagen::examples /// @returns The position of the row that was moved into the erased row's position, if any. /// /// @availability This method is only available when all the column types are move-assignable. - SOAGEN_HIDDEN(template >) + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = soagen::has_unordered_erase_member) SOAGEN_ALWAYS_INLINE SOAGEN_CPP20_CONSTEXPR // SOAGEN_ENABLE_IF_T(soagen::optional, sfinae) unordered_erase(size_type pos) // - noexcept(soagen::has_nothrow_unordered_erase_member) + noexcept(soagen::has_nothrow_unordered_erase_member) // { return table_.unordered_erase(pos); } @@ -1744,11 +1711,11 @@ namespace soagen::examples /// or #end() if the one removed was the last row in the table. /// /// @availability This method is only available when all the column types are move-assignable. - SOAGEN_HIDDEN(template >) + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = soagen::has_erase_member) SOAGEN_ALWAYS_INLINE SOAGEN_CPP20_CONSTEXPR - SOAGEN_ENABLE_IF_T(iterator, sfinae) erase(iterator pos) // - noexcept(soagen::has_nothrow_erase_member) + SOAGEN_ENABLE_IF_T(iterator, sfinae) erase(iterator pos) // + noexcept(soagen::has_nothrow_erase_member) // { table_.erase(static_cast(pos)); return pos; @@ -1766,11 +1733,11 @@ namespace soagen::examples /// @returns The position of the row that was moved into the erased row's position, if any. /// /// @availability This method is only available when all the column types are move-assignable. - SOAGEN_HIDDEN(template >) + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = soagen::has_unordered_erase_member) SOAGEN_ALWAYS_INLINE SOAGEN_CPP20_CONSTEXPR SOAGEN_ENABLE_IF_T(soagen::optional, sfinae) unordered_erase(iterator pos) // - noexcept(soagen::has_nothrow_unordered_erase_member) + noexcept(soagen::has_nothrow_unordered_erase_member) // { if (auto moved_pos = table_.unordered_erase(static_cast(pos)); moved_pos) return iterator{ *this, static_cast(*moved_pos) }; @@ -1783,11 +1750,11 @@ namespace soagen::examples /// or #cend() if the one removed was the last row in the table. /// /// @availability This method is only available when all the column types are move-assignable. - SOAGEN_HIDDEN(template >) + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = soagen::has_erase_member) SOAGEN_ALWAYS_INLINE SOAGEN_CPP20_CONSTEXPR SOAGEN_ENABLE_IF_T(const_iterator, sfinae) erase(const_iterator pos) // - noexcept(soagen::has_nothrow_erase_member) + noexcept(soagen::has_nothrow_erase_member) // { table_.erase(static_cast(pos)); return pos; @@ -1805,11 +1772,11 @@ namespace soagen::examples /// @returns The position of the row that was moved into the erased row's position, if any. /// /// @availability This method is only available when all the column types are move-assignable. - SOAGEN_HIDDEN(template >) + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = soagen::has_unordered_erase_member) SOAGEN_ALWAYS_INLINE SOAGEN_CPP20_CONSTEXPR SOAGEN_ENABLE_IF_T(soagen::optional, sfinae) unordered_erase(const_iterator pos) // - noexcept(soagen::has_nothrow_unordered_erase_member) + noexcept(soagen::has_nothrow_unordered_erase_member) // { if (auto moved_pos = table_.unordered_erase(static_cast(pos)); moved_pos) return const_iterator{ *this, static_cast(*moved_pos) }; @@ -1857,6 +1824,8 @@ namespace soagen::examples /// @name Adding rows /// @{ + // ------ push_back() -------------------------------------------------------------------------- + /// @brief Adds a new row at the end of the table. SOAGEN_CPP20_CONSTEXPR spheres& push_back(column_traits<0>::param_type center_x, @@ -1875,15 +1844,14 @@ namespace soagen::examples } /// @brief Adds a new row at the end of the table (rvalue overload). - SOAGEN_HIDDEN(template ) + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = table_traits::rvalues_are_distinct) SOAGEN_CPP20_CONSTEXPR - spheres& push_back(SOAGEN_ENABLE_IF_T(column_traits<0>::rvalue_type, sfinae) center_x, + spheres& push_back(column_traits<0>::rvalue_type center_x, column_traits<1>::rvalue_type center_y, column_traits<2>::rvalue_type center_z, column_traits<3>::rvalue_type radius = 0.5, column_traits<4>::rvalue_type mass = default_mass) // noexcept(table_traits::rvalue_push_back_is_nothrow) // - SOAGEN_REQUIRES(table_traits::rvalues_are_distinct) // { table_.emplace_back(static_cast::rvalue_forward_type>(center_x), static_cast::rvalue_forward_type>(center_y), @@ -1893,13 +1861,16 @@ namespace soagen::examples return *this; } + // ------ emplace_back() ----------------------------------------------------------------------- + /// @brief Constructs a new row directly in-place at the end of the table. - template ::default_emplace_type, - typename Mass = column_traits<4>::default_emplace_type SOAGEN_ENABLE_IF( - table_traits::row_constructible_from)> + SOAGEN_CONSTRAINED_TEMPLATE( + (table_traits::row_constructible_from), // + typename CenterX, + typename CenterY, + typename CenterZ, + typename Radius = column_traits<3>::default_emplace_type, + typename Mass = column_traits<4>::default_emplace_type) // SOAGEN_CPP20_CONSTEXPR spheres& emplace_back(CenterX&& center_x, CenterY&& center_y, @@ -1908,7 +1879,6 @@ namespace soagen::examples Mass&& mass = default_mass) // noexcept( table_traits::emplace_back_is_nothrow) // - SOAGEN_REQUIRES(table_traits::row_constructible_from) // { table_.emplace_back(static_cast(center_x), static_cast(center_y), @@ -1919,11 +1889,10 @@ namespace soagen::examples } /// @brief Constructs a new row directly in-place at the end of the table by unpacking a tuple-like object. - template )> + SOAGEN_CONSTRAINED_TEMPLATE(table_traits::row_constructible_from, typename Tuple) SOAGEN_CPP20_CONSTEXPR spheres& emplace_back(Tuple&& tuple_) // noexcept(table_traits::emplace_back_is_nothrow) // - SOAGEN_REQUIRES(table_traits::row_constructible_from) // { table_.emplace_back(static_cast(tuple_)); return *this; @@ -1932,24 +1901,34 @@ namespace soagen::examples /// @} /// @name Inserting rows - /// @availability These overloads are only available when all the column types are move-constructible and move-assignable. + /// @availability These overloads are only available when all the column types are move/copy-constructible and move/copy-assignable. /// @{ + private: + /// @cond + + static constexpr bool can_insert_ = + table_traits::all_move_or_copy_constructible && table_traits::all_move_or_copy_assignable; + + static constexpr bool can_insert_rvalues_ = can_insert_ && table_traits::rvalues_are_distinct; + + /// @endcond + + public: + // ------ insert(size_type) -------------------------------------------------------------------- + /// @brief Inserts a new row at an arbitrary position in the table. /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - SOAGEN_HIDDEN(template - ) + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = can_insert_) // SOAGEN_CPP20_CONSTEXPR SOAGEN_ENABLE_IF_T(spheres&, sfinae) insert(size_type index_, column_traits<0>::param_type center_x, column_traits<1>::param_type center_y, column_traits<2>::param_type center_z, column_traits<3>::param_type radius = 0.5, - column_traits<4>::param_type mass = default_mass) // - noexcept(table_traits::insert_is_nothrow) // - SOAGEN_REQUIRES(table_traits::all_move_or_copy_constructible&& table_traits::all_move_or_copy_assignable) // + column_traits<4>::param_type mass = default_mass) // + noexcept(table_traits::insert_is_nothrow) // { table_.emplace(index_, static_cast::param_forward_type>(center_x), @@ -1960,21 +1939,42 @@ namespace soagen::examples return *this; } + /// @brief Inserts a new row at an arbitrary position in the table (rvalue overload). + /// + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = can_insert_rvalues_) // + SOAGEN_CPP20_CONSTEXPR + spheres& insert(SOAGEN_ENABLE_IF_T(size_type, sfinae) index_, + column_traits<0>::rvalue_type center_x, + column_traits<1>::rvalue_type center_y, + column_traits<2>::rvalue_type center_z, + column_traits<3>::rvalue_type radius = 0.5, + column_traits<4>::rvalue_type mass = default_mass) // + noexcept(table_traits::insert_is_nothrow) // + { + table_.emplace(index_, + static_cast::rvalue_forward_type>(center_x), + static_cast::rvalue_forward_type>(center_y), + static_cast::rvalue_forward_type>(center_z), + static_cast::rvalue_forward_type>(radius), + static_cast::rvalue_forward_type>(mass)); + return *this; + } + + // ------ insert(iterator) --------------------------------------------------------------------- + /// @brief Inserts a new row at an arbitrary position in the table. /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - SOAGEN_HIDDEN(template - ) + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = can_insert_) // SOAGEN_CPP20_CONSTEXPR SOAGEN_ENABLE_IF_T(iterator, sfinae) insert(iterator iter_, column_traits<0>::param_type center_x, column_traits<1>::param_type center_y, column_traits<2>::param_type center_z, column_traits<3>::param_type radius = 0.5, - column_traits<4>::param_type mass = default_mass) // - noexcept(table_traits::insert_is_nothrow) // - SOAGEN_REQUIRES(table_traits::all_move_or_copy_constructible&& table_traits::all_move_or_copy_assignable) // + column_traits<4>::param_type mass = default_mass) // + noexcept(table_traits::insert_is_nothrow) // { table_.emplace(static_cast(iter_), static_cast::param_forward_type>(center_x), @@ -1987,19 +1987,16 @@ namespace soagen::examples /// @brief Inserts a new row at an arbitrary position in the table. /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - SOAGEN_HIDDEN(template - ) + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = can_insert_) // SOAGEN_CPP20_CONSTEXPR SOAGEN_ENABLE_IF_T(const_iterator, sfinae) insert(const_iterator iter_, column_traits<0>::param_type center_x, column_traits<1>::param_type center_y, column_traits<2>::param_type center_z, column_traits<3>::param_type radius = 0.5, - column_traits<4>::param_type mass = default_mass) // - noexcept(table_traits::insert_is_nothrow) // - SOAGEN_REQUIRES(table_traits::all_move_or_copy_constructible&& table_traits::all_move_or_copy_assignable) // + column_traits<4>::param_type mass = default_mass) // + noexcept(table_traits::insert_is_nothrow) // { table_.emplace(static_cast(iter_), static_cast::param_forward_type>(center_x), @@ -2012,38 +2009,8 @@ namespace soagen::examples /// @brief Inserts a new row at an arbitrary position in the table (rvalue overload). /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - SOAGEN_HIDDEN( - template - ) - SOAGEN_CPP20_CONSTEXPR - spheres& insert(SOAGEN_ENABLE_IF_T(size_type, sfinae) index_, - column_traits<0>::rvalue_type center_x, - column_traits<1>::rvalue_type center_y, - column_traits<2>::rvalue_type center_z, - column_traits<3>::rvalue_type radius = 0.5, - column_traits<4>::rvalue_type mass = default_mass) // - noexcept(table_traits::rvalue_insert_is_nothrow) // - SOAGEN_REQUIRES(table_traits::rvalues_are_distinct&& table_traits::all_move_or_copy_constructible&& - table_traits::all_move_or_copy_assignable) // - { - table_.emplace(index_, - static_cast::rvalue_forward_type>(center_x), - static_cast::rvalue_forward_type>(center_y), - static_cast::rvalue_forward_type>(center_z), - static_cast::rvalue_forward_type>(radius), - static_cast::rvalue_forward_type>(mass)); - return *this; - } - - /// @brief Inserts a new row at an arbitrary position in the table (rvalue overload). - /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - SOAGEN_HIDDEN( - template - ) + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = can_insert_rvalues_) // SOAGEN_CPP20_CONSTEXPR iterator insert(SOAGEN_ENABLE_IF_T(iterator, sfinae) iter_, column_traits<0>::rvalue_type center_x, @@ -2051,9 +2018,7 @@ namespace soagen::examples column_traits<2>::rvalue_type center_z, column_traits<3>::rvalue_type radius = 0.5, column_traits<4>::rvalue_type mass = default_mass) // - noexcept(table_traits::rvalue_insert_is_nothrow) // - SOAGEN_REQUIRES(table_traits::rvalues_are_distinct&& table_traits::all_move_or_copy_constructible&& - table_traits::all_move_or_copy_assignable) // + noexcept(table_traits::insert_is_nothrow) // { table_.emplace(static_cast(iter_), static_cast::rvalue_forward_type>(center_x), @@ -2066,11 +2031,8 @@ namespace soagen::examples /// @brief Inserts a new row at an arbitrary position in the table (rvalue overload). /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - SOAGEN_HIDDEN( - template - ) + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = can_insert_rvalues_) // SOAGEN_CPP20_CONSTEXPR const_iterator insert(SOAGEN_ENABLE_IF_T(const_iterator, sfinae) iter_, column_traits<0>::rvalue_type center_x, @@ -2078,9 +2040,7 @@ namespace soagen::examples column_traits<2>::rvalue_type center_z, column_traits<3>::rvalue_type radius = 0.5, column_traits<4>::rvalue_type mass = default_mass) // - noexcept(table_traits::rvalue_insert_is_nothrow) // - SOAGEN_REQUIRES(table_traits::rvalues_are_distinct&& table_traits::all_move_or_copy_constructible&& - table_traits::all_move_or_copy_assignable) // + noexcept(table_traits::insert_is_nothrow) // { table_.emplace(static_cast(iter_), static_cast::rvalue_forward_type>(center_x), @@ -2091,27 +2051,28 @@ namespace soagen::examples return iter_; } + // ------ emplace(size_type) ------------------------------------------------------------------- + /// @brief Constructs a new row directly in-place at an arbitrary position in the table. /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - template ::default_emplace_type, - typename Mass = column_traits<4>::default_emplace_type SOAGEN_ENABLE_IF( - (table_traits::all_move_or_copy_constructible && table_traits::all_move_or_copy_assignable - && table_traits::row_constructible_from))> + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_CONSTRAINED_TEMPLATE( + sfinae, + typename CenterX, + typename CenterY, + typename CenterZ, + typename Radius = column_traits<3>::default_emplace_type, + typename Mass = column_traits<4>::default_emplace_type SOAGEN_HIDDEN_PARAM( + bool sfinae = table_traits::row_constructible_from + && can_insert_)) // SOAGEN_CPP20_CONSTEXPR - spheres& emplace(size_type index_, - CenterX&& center_x, - CenterY&& center_y, - CenterZ&& center_z, - Radius&& radius = 0.5, - Mass&& mass = default_mass) // + SOAGEN_ENABLE_IF_T(spheres&, sfinae) emplace(size_type index_, + CenterX&& center_x, + CenterY&& center_y, + CenterZ&& center_z, + Radius&& radius = 0.5, + Mass&& mass = default_mass) // noexcept(table_traits::emplace_is_nothrow) // - SOAGEN_REQUIRES( - table_traits::all_move_or_copy_constructible&& table_traits::all_move_or_copy_assignable&& - table_traits::row_constructible_from) // { table_.emplace(index_, static_cast(center_x), @@ -2122,58 +2083,42 @@ namespace soagen::examples return *this; } - /// @brief Constructs a new row directly in-place at an arbitrary position in the table. + /// @brief Constructs a new row directly in-place at an arbitrary position in the table by unpacking a tuple-like object. /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - template ::default_emplace_type, - typename Mass = column_traits<4>::default_emplace_type SOAGEN_ENABLE_IF( - (table_traits::all_move_or_copy_constructible && table_traits::all_move_or_copy_assignable - && table_traits::row_constructible_from))> + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_CONSTRAINED_TEMPLATE(sfinae, + typename Tuple SOAGEN_HIDDEN_PARAM( + bool sfinae = table_traits::row_constructible_from && can_insert_)) // SOAGEN_CPP20_CONSTEXPR - iterator emplace(iterator iter_, - CenterX&& center_x, - CenterY&& center_y, - CenterZ&& center_z, - Radius&& radius = 0.5, - Mass&& mass = default_mass) // - noexcept(table_traits::emplace_is_nothrow) // - SOAGEN_REQUIRES( - table_traits::all_move_or_copy_constructible&& table_traits::all_move_or_copy_assignable&& - table_traits::row_constructible_from) // + spheres& emplace(SOAGEN_ENABLE_IF_T(size_type, sfinae) index_, Tuple&& tuple_) // + noexcept(table_traits::emplace_is_nothrow) // { - table_.emplace(static_cast(iter_), - static_cast(center_x), - static_cast(center_y), - static_cast(center_z), - static_cast(radius), - static_cast(mass)); - return iter_; + table_.emplace(index_, static_cast(tuple_)); + return *this; } + // ------ emplace(iterator) -------------------------------------------------------------------- + /// @brief Constructs a new row directly in-place at an arbitrary position in the table. /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - template ::default_emplace_type, - typename Mass = column_traits<4>::default_emplace_type SOAGEN_ENABLE_IF( - (table_traits::all_move_or_copy_constructible && table_traits::all_move_or_copy_assignable - && table_traits::row_constructible_from))> + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_CONSTRAINED_TEMPLATE( + sfinae, + typename CenterX, + typename CenterY, + typename CenterZ, + typename Radius = column_traits<3>::default_emplace_type, + typename Mass = column_traits<4>::default_emplace_type SOAGEN_HIDDEN_PARAM( + bool sfinae = table_traits::row_constructible_from + && can_insert_)) // SOAGEN_CPP20_CONSTEXPR - const_iterator emplace(const_iterator iter_, - CenterX&& center_x, - CenterY&& center_y, - CenterZ&& center_z, - Radius&& radius = 0.5, - Mass&& mass = default_mass) // + SOAGEN_ENABLE_IF_T(iterator, sfinae) emplace(iterator iter_, + CenterX&& center_x, + CenterY&& center_y, + CenterZ&& center_z, + Radius&& radius = 0.5, + Mass&& mass = default_mass) // noexcept(table_traits::emplace_is_nothrow) // - SOAGEN_REQUIRES( - table_traits::all_move_or_copy_constructible&& table_traits::all_move_or_copy_assignable&& - table_traits::row_constructible_from) // { table_.emplace(static_cast(iter_), static_cast(center_x), @@ -2186,50 +2131,57 @@ namespace soagen::examples /// @brief Constructs a new row directly in-place at an arbitrary position in the table by unpacking a tuple-like object. /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - template - && table_traits::all_move_or_copy_constructible - && table_traits::all_move_or_copy_assignable))> + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_CONSTRAINED_TEMPLATE(sfinae, + typename Tuple SOAGEN_HIDDEN_PARAM( + bool sfinae = table_traits::row_constructible_from && can_insert_)) // SOAGEN_CPP20_CONSTEXPR - spheres& emplace(size_type index_, Tuple&& tuple_) // - noexcept(table_traits::emplace_is_nothrow) // - SOAGEN_REQUIRES( - table_traits::row_constructible_from&& table_traits::all_move_or_copy_constructible&& - table_traits::all_move_or_copy_assignable) // + iterator emplace(SOAGEN_ENABLE_IF_T(iterator, sfinae) iter_, Tuple&& tuple_) // + noexcept(table_traits::emplace_is_nothrow) // { - table_.emplace(index_, static_cast(tuple_)); - return *this; + table_.emplace(static_cast(iter_), static_cast(tuple_)); + return iter_; } - /// @brief Constructs a new row directly in-place at an arbitrary position in the table by unpacking a tuple-like object. + /// @brief Constructs a new row directly in-place at an arbitrary position in the table. /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - template - && table_traits::all_move_or_copy_constructible - && table_traits::all_move_or_copy_assignable))> + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_CONSTRAINED_TEMPLATE( + sfinae, + typename CenterX, + typename CenterY, + typename CenterZ, + typename Radius = column_traits<3>::default_emplace_type, + typename Mass = column_traits<4>::default_emplace_type SOAGEN_HIDDEN_PARAM( + bool sfinae = table_traits::row_constructible_from + && can_insert_)) // SOAGEN_CPP20_CONSTEXPR - iterator emplace(iterator iter_, Tuple&& tuple_) // - noexcept(table_traits::emplace_is_nothrow) // - SOAGEN_REQUIRES( - table_traits::row_constructible_from&& table_traits::all_move_or_copy_constructible&& - table_traits::all_move_or_copy_assignable) // + SOAGEN_ENABLE_IF_T(const_iterator, sfinae) emplace(const_iterator iter_, + CenterX&& center_x, + CenterY&& center_y, + CenterZ&& center_z, + Radius&& radius = 0.5, + Mass&& mass = default_mass) // + noexcept(table_traits::emplace_is_nothrow) // { - table_.emplace(static_cast(iter_), static_cast(tuple_)); + table_.emplace(static_cast(iter_), + static_cast(center_x), + static_cast(center_y), + static_cast(center_z), + static_cast(radius), + static_cast(mass)); return iter_; } /// @brief Constructs a new row directly in-place at an arbitrary position in the table by unpacking a tuple-like object. /// - /// @availability This overload is only available when all the column types are move-constructible and move-assignable. - template - && table_traits::all_move_or_copy_constructible - && table_traits::all_move_or_copy_assignable))> + /// @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable. + SOAGEN_CONSTRAINED_TEMPLATE(sfinae, + typename Tuple SOAGEN_HIDDEN_PARAM( + bool sfinae = table_traits::row_constructible_from && can_insert_)) // SOAGEN_CPP20_CONSTEXPR - const_iterator emplace(const_iterator iter_, Tuple&& tuple_) // - noexcept(table_traits::emplace_is_nothrow) // - SOAGEN_REQUIRES( - table_traits::row_constructible_from&& table_traits::all_move_or_copy_constructible&& - table_traits::all_move_or_copy_assignable) // + const_iterator emplace(SOAGEN_ENABLE_IF_T(const_iterator, sfinae) iter_, Tuple&& tuple_) // + noexcept(table_traits::emplace_is_nothrow) // { table_.emplace(static_cast(iter_), static_cast(tuple_)); return iter_; diff --git a/src/soagen/header_file.py b/src/soagen/header_file.py index f28e59f..ad41e4b 100644 --- a/src/soagen/header_file.py +++ b/src/soagen/header_file.py @@ -156,6 +156,9 @@ def write(self, o: Writer): #if defined(DOXYGEN) || defined(__DOXYGEN) || defined(__DOXYGEN__) \ || defined(__doxygen__) || defined(__POXY__) || defined(__poxy__) + #ifndef SOAGEN_CONSTRAINED_TEMPLATE + #define SOAGEN_CONSTRAINED_TEMPLATE(cond, ...) template <__VA_ARGS__> + #endif #ifndef SOAGEN_DOXYGEN #define SOAGEN_DOXYGEN 1 #endif diff --git a/src/soagen/hpp/iterator.hpp b/src/soagen/hpp/iterator.hpp index 3ac3dff..539c05b 100644 --- a/src/soagen/hpp/iterator.hpp +++ b/src/soagen/hpp/iterator.hpp @@ -337,6 +337,14 @@ namespace soagen return iterator{ static_cast(*this) }; } + SOAGEN_PURE_INLINE_GETTER + explicit constexpr operator size_type() const noexcept + { + SOAGEN_ASSUME(base::offset >= 0); + + return static_cast(base::offset); + } + /// @endcond /// @brief Converts this iterator to it's underlying #difference_type value. @@ -346,14 +354,6 @@ namespace soagen return base::offset; } - SOAGEN_PURE_INLINE_GETTER - explicit constexpr operator size_type() const noexcept - { - SOAGEN_ASSUME(base::offset >= 0); - - return static_cast(base::offset); - } - /// @} }; diff --git a/src/soagen/hpp/single/soagen.hpp b/src/soagen/hpp/single/soagen.hpp index 5f66e39..5d9ea32 100644 --- a/src/soagen/hpp/single/soagen.hpp +++ b/src/soagen/hpp/single/soagen.hpp @@ -1019,7 +1019,7 @@ SOAGEN_ENABLE_WARNINGS; #endif #if !defined(__POXY__) && !defined(POXY_IMPLEMENTATION_DETAIL) - #define ...) __VA_ARGS__ + #define POXY_IMPLEMENTATION_DETAIL(...) __VA_ARGS__ #endif //******** generated/functions.hpp *********************************************************************************** @@ -1070,7 +1070,7 @@ namespace soagen #elif SOAGEN_CLANG >= 9 || SOAGEN_GCC >= 9 || SOAGEN_MSVC >= 1925 || SOAGEN_HAS_BUILTIN(is_constant_evaluated) - return __builtin_is_constant_evaluated(; + return __builtin_is_constant_evaluated(); #elif defined(__cpp_lib_is_constant_evaluated) && __cpp_lib_is_constant_evaluated >= 201811 @@ -4702,8 +4702,7 @@ namespace soagen::detail } catch (...) { - for (; i-- > start;) - destruct_row(columns, i); + destruct_rows(columns, start, i - start); throw; } } @@ -4775,7 +4774,6 @@ namespace soagen::detail { if (constructed_columns) destruct_row(columns, index, 0u, constructed_columns - 1u); - throw; } } @@ -4824,7 +4822,6 @@ namespace soagen::detail { if (constructed_columns) destruct_row(dest, dest_index, 0u, constructed_columns - 1u); - throw; } } @@ -4846,26 +4843,11 @@ namespace soagen::detail { memmove(dest, dest_start, source, source_start, count); } - else if constexpr (all_nothrow_move_constructible) - { - if (&dest == &source && dest_start > source_start) - { - for (size_t i = count; i-- > 0u;) - move_construct_row(dest, dest_start + i, source, source_start + i); - } - else - { - for (size_t i = 0; i < count; i++) - move_construct_row(dest, dest_start + i, source, source_start + i); - } - } else { - // machinery to provide strong-exception guarantee + [[maybe_unused]] size_t i = 0; - size_t i = 0; - - try + const auto constructor = [&]() noexcept(all_nothrow_move_constructible) { if (&dest == &source && dest_start > source_start) { @@ -4877,20 +4859,25 @@ namespace soagen::detail for (; i < count; i++) move_construct_row(dest, dest_start + i, source, source_start + i); } + }; + + if constexpr (all_nothrow_move_constructible) + { + constructor(); } - catch (...) + else { - if (&dest == &source && dest_start > source_start) + // machinery to provide strong-exception guarantee + + try { - for (; i < count; i++) - destruct_row(dest, dest_start + i); + constructor(); } - else + catch (...) { - for (; i-- > 0u;) - destruct_row(dest, dest_start + i); + destruct_rows(dest, dest_start, i - dest_start); + throw; } - throw; } } } @@ -4959,26 +4946,11 @@ namespace soagen::detail { memmove(dest, dest_start, source, source_start, count); } - else if constexpr (all_nothrow_copy_constructible) - { - if (&dest == &source && dest_start > source_start) - { - for (size_t i = count; i-- > 0u;) - copy_construct_row(dest, dest_start + i, source, source_start + i); - } - else - { - for (size_t i = 0; i < count; i++) - copy_construct_row(dest, dest_start + i, source, source_start + i); - } - } else { - // machinery to provide strong-exception guarantee - - size_t i = 0; + [[maybe_unused]] size_t i = 0; - try + const auto constructor = [&]() noexcept(all_nothrow_copy_constructible) { if (&dest == &source && dest_start > source_start) { @@ -4990,20 +4962,25 @@ namespace soagen::detail for (; i < count; i++) copy_construct_row(dest, dest_start + i, source, source_start + i); } + }; + + if constexpr (all_nothrow_copy_constructible) + { + constructor(); } - catch (...) + else { - if (&dest == &source && dest_start > source_start) + // machinery to provide strong-exception guarantee + + try { - for (; i < count; i++) - destruct_row(dest, dest_start + i); + constructor(); } - else + catch (...) { - for (; i-- > 0u;) - destruct_row(dest, dest_start + i); + destruct_rows(dest, dest_start, i - dest_start); + throw; } - throw; } } } @@ -5072,26 +5049,11 @@ namespace soagen::detail { memmove(dest, dest_start, source, source_start, count); } - else if constexpr (all_nothrow_move_or_copy_constructible) - { - if (&dest == &source && dest_start > source_start) - { - for (size_t i = count; i-- > 0u;) - move_or_copy_construct_row(dest, dest_start + i, source, source_start + i); - } - else - { - for (size_t i = 0; i < count; i++) - move_or_copy_construct_row(dest, dest_start + i, source, source_start + i); - } - } else { - // machinery to provide strong-exception guarantee - - size_t i = 0; + [[maybe_unused]] size_t i = 0; - try + const auto constructor = [&]() noexcept(all_nothrow_move_or_copy_constructible) { if (&dest == &source && dest_start > source_start) { @@ -5103,20 +5065,25 @@ namespace soagen::detail for (; i < count; i++) move_or_copy_construct_row(dest, dest_start + i, source, source_start + i); } + }; + + if constexpr (all_nothrow_move_or_copy_constructible) + { + constructor(); } - catch (...) + else { - if (&dest == &source && dest_start > source_start) + // machinery to provide strong-exception guarantee + + try { - for (; i < count; i++) - move_or_copy_construct_row(dest, dest_start + i); + constructor(); } - else + catch (...) { - for (; i-- > 0u;) - move_or_copy_construct_row(dest, dest_start + i); + destruct_rows(dest, dest_start, i - dest_start); + throw; } - throw; } } } @@ -5695,12 +5662,6 @@ namespace soagen return iterator{ static_cast(*this) }; } - SOAGEN_PURE_INLINE_GETTER - explicit constexpr operator difference_type() const noexcept - { - return base::offset; - } - SOAGEN_PURE_INLINE_GETTER explicit constexpr operator size_type() const noexcept { @@ -5708,6 +5669,12 @@ namespace soagen return static_cast(base::offset); } + + SOAGEN_PURE_INLINE_GETTER + explicit constexpr operator difference_type() const noexcept + { + return base::offset; + } }; template diff --git a/src/soagen/hpp/table_traits.hpp b/src/soagen/hpp/table_traits.hpp index 2a945b3..8839346 100644 --- a/src/soagen/hpp/table_traits.hpp +++ b/src/soagen/hpp/table_traits.hpp @@ -370,8 +370,7 @@ namespace soagen::detail } catch (...) { - for (; i-- > start;) - destruct_row(columns, i); + destruct_rows(columns, start, i - start); throw; } } @@ -443,7 +442,6 @@ namespace soagen::detail { if (constructed_columns) destruct_row(columns, index, 0u, constructed_columns - 1u); - throw; } } @@ -492,7 +490,6 @@ namespace soagen::detail { if (constructed_columns) destruct_row(dest, dest_index, 0u, constructed_columns - 1u); - throw; } } @@ -514,26 +511,11 @@ namespace soagen::detail { memmove(dest, dest_start, source, source_start, count); } - else if constexpr (all_nothrow_move_constructible) - { - if (&dest == &source && dest_start > source_start) - { - for (size_t i = count; i-- > 0u;) - move_construct_row(dest, dest_start + i, source, source_start + i); - } - else - { - for (size_t i = 0; i < count; i++) - move_construct_row(dest, dest_start + i, source, source_start + i); - } - } else { - // machinery to provide strong-exception guarantee - - size_t i = 0; + [[maybe_unused]] size_t i = 0; - try + const auto constructor = [&]() noexcept(all_nothrow_move_constructible) { if (&dest == &source && dest_start > source_start) { @@ -545,20 +527,25 @@ namespace soagen::detail for (; i < count; i++) move_construct_row(dest, dest_start + i, source, source_start + i); } + }; + + if constexpr (all_nothrow_move_constructible) + { + constructor(); } - catch (...) + else { - if (&dest == &source && dest_start > source_start) + // machinery to provide strong-exception guarantee + + try { - for (; i < count; i++) - destruct_row(dest, dest_start + i); + constructor(); } - else + catch (...) { - for (; i-- > 0u;) - destruct_row(dest, dest_start + i); + destruct_rows(dest, dest_start, i - dest_start); + throw; } - throw; } } } @@ -627,26 +614,11 @@ namespace soagen::detail { memmove(dest, dest_start, source, source_start, count); } - else if constexpr (all_nothrow_copy_constructible) - { - if (&dest == &source && dest_start > source_start) - { - for (size_t i = count; i-- > 0u;) - copy_construct_row(dest, dest_start + i, source, source_start + i); - } - else - { - for (size_t i = 0; i < count; i++) - copy_construct_row(dest, dest_start + i, source, source_start + i); - } - } else { - // machinery to provide strong-exception guarantee + [[maybe_unused]] size_t i = 0; - size_t i = 0; - - try + const auto constructor = [&]() noexcept(all_nothrow_copy_constructible) { if (&dest == &source && dest_start > source_start) { @@ -658,20 +630,25 @@ namespace soagen::detail for (; i < count; i++) copy_construct_row(dest, dest_start + i, source, source_start + i); } + }; + + if constexpr (all_nothrow_copy_constructible) + { + constructor(); } - catch (...) + else { - if (&dest == &source && dest_start > source_start) + // machinery to provide strong-exception guarantee + + try { - for (; i < count; i++) - destruct_row(dest, dest_start + i); + constructor(); } - else + catch (...) { - for (; i-- > 0u;) - destruct_row(dest, dest_start + i); + destruct_rows(dest, dest_start, i - dest_start); + throw; } - throw; } } } @@ -740,26 +717,11 @@ namespace soagen::detail { memmove(dest, dest_start, source, source_start, count); } - else if constexpr (all_nothrow_move_or_copy_constructible) - { - if (&dest == &source && dest_start > source_start) - { - for (size_t i = count; i-- > 0u;) - move_or_copy_construct_row(dest, dest_start + i, source, source_start + i); - } - else - { - for (size_t i = 0; i < count; i++) - move_or_copy_construct_row(dest, dest_start + i, source, source_start + i); - } - } else { - // machinery to provide strong-exception guarantee - - size_t i = 0; + [[maybe_unused]] size_t i = 0; - try + const auto constructor = [&]() noexcept(all_nothrow_move_or_copy_constructible) { if (&dest == &source && dest_start > source_start) { @@ -771,20 +733,25 @@ namespace soagen::detail for (; i < count; i++) move_or_copy_construct_row(dest, dest_start + i, source, source_start + i); } + }; + + if constexpr (all_nothrow_move_or_copy_constructible) + { + constructor(); } - catch (...) + else { - if (&dest == &source && dest_start > source_start) + // machinery to provide strong-exception guarantee + + try { - for (; i < count; i++) - move_or_copy_construct_row(dest, dest_start + i); + constructor(); } - else + catch (...) { - for (; i-- > 0u;) - move_or_copy_construct_row(dest, dest_start + i); + destruct_rows(dest, dest_start, i - dest_start); + throw; } - throw; } } } diff --git a/src/soagen/main.py b/src/soagen/main.py index 0a9c20f..133a48c 100644 --- a/src/soagen/main.py +++ b/src/soagen/main.py @@ -485,12 +485,7 @@ def on_flush(o: Writer, s: str) -> str: s, flags=re.DOTALL, ) - s = re.sub( - r'SOAGEN_HIDDEN_PARAM\s*\(\s*bool\s*sfinae\s*=\s*\(\s*(.+?)\s*\)\s*\)', # two sets of brackets - r', bool sfinae = (\1)', - s, - flags=re.DOTALL, - ) + s = re.sub(r'SOAGEN_HIDDEN_PARAM\s*\(\s*(.+?)\s*\)', r', \1', s, flags=re.DOTALL) s = re.sub(r'SOAGEN_HIDDEN_BASE\s*\(\s*(.+?)\s*\)', r': \1', s, flags=re.DOTALL) s = re.sub( r'SOAGEN_HIDDEN\s*\(\s*template\s*<(.+?)\s*>\s*\)', r'template <\1>', s, flags=re.DOTALL diff --git a/src/soagen/preprocessor.py b/src/soagen/preprocessor.py index 206a274..f9ef947 100644 --- a/src/soagen/preprocessor.py +++ b/src/soagen/preprocessor.py @@ -96,6 +96,9 @@ def __init__(self, file): self.__entry_root = None self.__string = self.__preprocess(file) # do some cleanup of the preprocessed file + self.__string = re.sub( + r'#\s*define\s+POXY_IMPLEMENTATION_DETAIL\s*\(', r'#define POXY_IMPLEMENTATION_DETAIL_____(', self.__string + ) while True: s = self.__string # misc cleanup @@ -119,6 +122,9 @@ def __init__(self, file): break self.__string = s self.__string = self.__string.strip() + '\n' + self.__string = re.sub( + r'#\s*define\s+POXY_IMPLEMENTATION_DETAIL_____\s*\(', r'#define POXY_IMPLEMENTATION_DETAIL(', self.__string + ) def __preprocess(self, incl): if not isinstance(incl, (Path, str)): # a regex match object diff --git a/src/soagen/struct.py b/src/soagen/struct.py index 34818f6..99ea2e4 100644 --- a/src/soagen/struct.py +++ b/src/soagen/struct.py @@ -348,11 +348,11 @@ def doxygen(s: str) -> str: {doxygen(r"@brief Gets the soagen::column_traits for a specific column of the table.")} template - using column_traits = typename table_traits::template column(Column)>; + using column_traits = POXY_IMPLEMENTATION_DETAIL(typename table_traits::template column(Column)>); {doxygen(r"@brief Gets the type of a specific column in the table.")} template - using column_type = typename column_traits(Column)>::value_type; + using column_type = POXY_IMPLEMENTATION_DETAIL(typename column_traits(Column)>::value_type); {doxygen(r"@brief Row iterators returned by iterator functions.")} using iterator = soagen::iterator_type<{self.name}>; @@ -564,11 +564,11 @@ def doxygen(s: str) -> str: @brief Erases the row at the given position. @availability This method is only available when all the column types are move-assignable.""")} - SOAGEN_HIDDEN(template >) + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = soagen::has_erase_member) SOAGEN_ALWAYS_INLINE SOAGEN_CPP20_CONSTEXPR // SOAGEN_ENABLE_IF_T({self.name}&, sfinae) erase(size_type pos) // - noexcept(soagen::has_nothrow_erase_member) + noexcept(soagen::has_nothrow_erase_member) // {{ table_.erase(pos); return *this; @@ -587,11 +587,11 @@ def doxygen(s: str) -> str: @returns The position of the row that was moved into the erased row's position, if any. @availability This method is only available when all the column types are move-assignable.""")} - SOAGEN_HIDDEN(template >) + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = soagen::has_unordered_erase_member) SOAGEN_ALWAYS_INLINE SOAGEN_CPP20_CONSTEXPR // SOAGEN_ENABLE_IF_T(soagen::optional, sfinae) unordered_erase(size_type pos) // - noexcept(soagen::has_nothrow_unordered_erase_member) + noexcept(soagen::has_nothrow_unordered_erase_member) // {{ return table_.unordered_erase(pos); }} @@ -608,11 +608,11 @@ def doxygen(s: str) -> str: or #{"c" if const else ""}end() if the one removed was the last row in the table. @availability This method is only available when all the column types are move-assignable.""")} - SOAGEN_HIDDEN(template >) + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = soagen::has_erase_member) SOAGEN_ALWAYS_INLINE SOAGEN_CPP20_CONSTEXPR SOAGEN_ENABLE_IF_T({const}iterator, sfinae) erase({const}iterator pos) // - noexcept(soagen::has_nothrow_erase_member) + noexcept(soagen::has_nothrow_erase_member) // {{ table_.erase(static_cast(pos)); return pos; @@ -631,11 +631,11 @@ def doxygen(s: str) -> str: @returns The position of the row that was moved into the erased row's position, if any. @availability This method is only available when all the column types are move-assignable.""")} - SOAGEN_HIDDEN(template >) + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = soagen::has_unordered_erase_member) SOAGEN_ALWAYS_INLINE SOAGEN_CPP20_CONSTEXPR SOAGEN_ENABLE_IF_T(soagen::optional<{const}iterator>, sfinae) unordered_erase({const}iterator pos) // - noexcept(soagen::has_nothrow_unordered_erase_member) + noexcept(soagen::has_nothrow_unordered_erase_member) // {{ if (auto moved_pos = table_.unordered_erase(static_cast(pos)); moved_pos) return {const}iterator{{ *this, static_cast(*moved_pos) }}; @@ -692,288 +692,283 @@ def doxygen(s: str) -> str: ''' ) - with Public(o): - for funcs, group, availability in ( - ((r'push_back', r'emplace_back'), r'Adding rows', ''), - ( - (r'insert', r'emplace'), - r'Inserting rows', - r'These overloads are only available when all the column types are move-constructible and move-assignable.', - ), - ): - sfinae_variant = -1 - sfinae_sig_hash = '' - with DoxygenMemberGroup(o, group, availability=availability): - for func in funcs: - for tuple_overload in (False, True): - if tuple_overload and func not in (r'emplace_back', r'emplace'): - continue - for rvalue_overload in (False, True): - if rvalue_overload and ( - tuple_overload or func in (r'emplace_back', r'emplace') - ): - continue - for iterator_overload in (None, r'iterator', r'const_iterator'): - if iterator_overload and func in (r'push_back', r'emplace_back'): - continue - - template_params = [] - template_defaults = [] - types = [] - names = [] - defaults = [] - forwards = [] - deduced = [] - sig_hash = func - - if func in (r'insert', r'emplace'): - defaults.append('') - if iterator_overload: - types.append(iterator_overload) - names.append(r'iter_') - forwards.append(r'static_cast(iter_)') - deduced.append(False) - else: - types.append(r'size_type') - names.append(r'index_') - forwards.append(names[-1]) - deduced.append(False) - - if tuple_overload: - template_params.append(r'typename Tuple') - template_defaults += [''] - types.append(r'Tuple&&') - names.append(r'tuple_') - deduced.append(True) - defaults.append('') - forwards.append(rf'static_cast<{types[-1]}>({names[-1]})') - else: - for col in self.columns: - names.append(col.name) - defaults.append(col.default) - if func in (r'emplace_back', r'emplace'): - typename = utils.to_pascal_case(col.name) - if typename == col.name: - typename = rf'{typename}T' - template_params.append(rf'typename {typename}') - template_defaults.append( - rf'column_traits<{col.index}>::default_emplace_type' - if col.default - else '' - ) - types.append(rf'{typename}&&') - forwards.append(rf'static_cast<{types[-1]}>({names[-1]})') - deduced.append(True) - else: - category = r'rvalue' if rvalue_overload else r'param' - types.append(rf'column_traits<{col.index}>::{category}_type') - forward_type = ( - rf'column_traits<{col.index}>::{category}_forward_type' - ) - forwards.append(rf'static_cast<{forward_type}>({names[-1]})') - deduced.append(False) - - sig_hash += '##'.join(types) - if not sfinae_sig_hash or sfinae_sig_hash != sig_hash: - sfinae_variant = 0 if rvalue_overload else -1 - sfinae_sig_hash = sig_hash - - sfinae = [] - sfinae_emitted = False - sfinae_template_dependent = False - sfinae_condition_string = '' - if tuple_overload: - sfinae.append(r'table_traits::row_constructible_from') - sfinae_template_dependent = True - if rvalue_overload: - sfinae.append(r'table_traits::rvalues_are_distinct') - if func in (r'insert', r'emplace'): - sfinae.append(r'table_traits::all_move_or_copy_constructible') - sfinae.append(r'table_traits::all_move_or_copy_assignable') - if func in (r'emplace_back', r'emplace') and not tuple_overload: - sfinae.append( - rf'table_traits::row_constructible_from<{",".join(types[-len(self.columns):])}>' - ) - sfinae_template_dependent = True - hidden_template = bool(sfinae) and not template_params - sfinae = utils.remove_duplicates(sfinae) - if sfinae: - if len(sfinae) > 2: - sfinae_condition_string = f'\n{o.indent_str*7}&& '.join(sfinae) - else: - sfinae_condition_string = r' && '.join(sfinae) - if len(sfinae) >= 2: - sfinae_condition_string = rf'({sfinae_condition_string})' - if sfinae_template_dependent: - template_params.append( - rf'SOAGEN_ENABLE_IF({sfinae_condition_string}' - ) - template_defaults.append(')') - sfinae_emitted = True - else: - if hidden_template: - template_params.append(r'bool sfinae') - template_defaults.append(sfinae_condition_string) - else: - template_params.append( - rf'SOAGEN_HIDDEN_PARAM(bool sfinae = {sfinae_condition_string}' - ) - template_defaults.append(')') - - defaults_ok = True - assert len(template_params) == len(template_defaults) - for i in range(len(template_defaults) - 1, -1, -1): - if not defaults_ok: - template_defaults[i] = '' - elif not template_defaults[i]: - defaults_ok = False - - defaults_ok = True - assert len(names) == len(defaults) - assert len(names) == len(types) - for i in range(len(defaults) - 1, -1, -1): - if not defaults_ok: - defaults[i] = '' - elif not defaults[i]: - defaults_ok = False - - s = '' - - # doxygen - if o.doxygen: - s += '/// @brief ' - if func in (r'emplace_back', r'emplace'): - s += 'Constructs a new row directly in-place' - elif func == r'insert': - s += 'Inserts a new row' - elif func == r'push_back': - s += 'Adds a new row' - if func in (r'insert', r'emplace'): - s += ' at an arbitrary position in the table' - elif func.endswith(r'_back'): - s += ' at the end of the table' - if tuple_overload: - s += ' by unpacking a tuple-like object' - if rvalue_overload: - s += ' (rvalue overload)' - s += '.\n' - if func in (r'insert', r'emplace'): - s += '///\n' - s += '/// @availability This overload is only available when all' - s += ' the column types are move-constructible and move-assignable.\n' - - # template <> - if template_params: - if hidden_template: - s += r'SOAGEN_HIDDEN(' - s += r'template <' - padding = f'\n{TAB_SPACES*2} ' if len(template_params) >= 3 else ' ' - for i in range(len(template_params)): - if i: - if not template_params[i].startswith( - 'SOAGEN_ENABLE_IF' - ) and not template_params[i].startswith('SOAGEN_HIDDEN'): - s += rf',' - s += rf'{padding}' - s += template_params[i] - if template_defaults[i] == ')': - s += ')' - elif template_defaults[i]: - s += rf' = {template_defaults[i]}' - s += r'>' - if hidden_template: - s += r')' - s += '\n' - - # attributes - s += 'SOAGEN_CPP20_CONSTEXPR\n' - - # return type - return_type = iterator_overload if iterator_overload else rf'{self.name}&' - return_expression = r'iter_' if iterator_overload else r'*this' - if sfinae and not sfinae_emitted and sfinae_variant == -1: - return_type = rf'SOAGEN_ENABLE_IF_T({return_type}, sfinae)' - sfinae_emitted = True - sfinae_variant += 1 - s += rf'{return_type} ' - - # name + args - s += rf'{func}(' - if types: - padding = ' ' * (len(func) + len(return_type) + 2) - padding = f'\n{padding}' if len(types) >= 3 else ' ' - for i in range(len(types)): - if i: - s += rf',{padding}' - if ( - sfinae - and not sfinae_emitted - and sfinae_variant == i - and types[i] - and not deduced[i] - in ( - 'size_t', - 'size_type', - 'iterator', - 'const_iterator', - rf'column_traits<{i-1}>::param_type', - rf'column_traits<{i-1}>::rvalue_type', - ) - ): - s += rf'SOAGEN_ENABLE_IF_T({types[i]}, sfinae)' - sfinae_emitted = True - sfinae_variant += 1 - else: - s += rf'{types[i]}' - s += rf' {names[i]}' - if defaults[i]: - s += rf' = {defaults[i]}' - s += ') //\n' - - # noexcept(...) - backing_func = ( - r'emplace' if func in (r'insert', r'emplace') else r'emplace_back' - ) - s += '\tnoexcept(' - if func == 'push_back': - if tuple_overload: - s += rf'table_traits::row_push_back_is_nothrow' - else: - s += rf'table_traits::{"rvalue_" if rvalue_overload else ""}push_back_is_nothrow' - elif func == 'insert': - if tuple_overload: - s += ( - rf'table_traits::row_insert_is_nothrow' - ) - else: - s += rf'table_traits::{"rvalue_" if rvalue_overload else ""}insert_is_nothrow' - elif func == 'emplace_back': - s += rf'table_traits::emplace_back_is_nothrow' - elif func == 'emplace': - s += rf'table_traits::emplace_is_nothrow' - else: - assert False # we should have all our bases covered by the table_traits - s += ') //\n' - - # requires(...) - if sfinae: - s += f'\tSOAGEN_REQUIRES({sfinae_condition_string.strip("()")}) //\n' - - # function body - s += '{\n' - s += f'\ttable_.{backing_func}(' - if forwards: - padding = f'\n{TAB_SPACES*2}' if len(forwards) >= 3 else ' ' - if len(forwards) >= 3: - s += padding - s += f',{padding}'.join(forwards) - s += f');\n' - if return_expression: - s += f'\treturn {return_expression};\n' - s += '}\n\n' - - assert not sfinae or sfinae_emitted - o(s) + # figure out defaults for function + template params + value_defaults = [] + type_defaults = [] + defaults_ok = True + for i in range(len(self.columns) - 1, -1, -1): + col = self.columns[i] + if not col.default: + defaults_ok = False + if defaults_ok: + value_defaults.append(col.default) + type_defaults.append(rf'column_traits<{col.index}>::default_emplace_type') + else: + value_defaults.append('') + type_defaults.append('') + value_defaults.reverse() + type_defaults.reverse() + + # param lists etc + lvalue_param_list = [] + lvalue_forward_list = [] + rvalue_param_list = [] + rvalue_forward_list = [] + template_type_names = [] + template_type_list = [] + template_params = [] + template_param_list = [] + template_forward_list = [] + for i in range(len(self.columns)): + col = self.columns[i] + # push_back + insert: + value_default = rf' = {value_defaults[i]}' if value_defaults[i] else '' + lvalue_param_list.append(rf'column_traits<{i}>::param_type {col.name}{value_default}') + lvalue_forward_list.append(rf'static_cast::param_forward_type>({col.name})') + rvalue_param_list.append(rf'column_traits<{i}>::rvalue_type {col.name}{value_default}') + rvalue_forward_list.append(rf'static_cast::rvalue_forward_type>({col.name})') + # emplace_back + emplace: + type_default = rf' = {type_defaults[i]}' if type_defaults[i] else '' + typename = utils.to_pascal_case(col.name) + if typename == col.name: + typename = rf'{typename}T' + template_type_names.append(typename) + template_params.append(typename + '&&') + template_type_list.append(rf'typename {typename}{type_default}') + template_param_list.append(rf'{typename}&& {col.name}{value_default}') + template_forward_list.append(rf'static_cast<{typename}&&>({col.name})') + + with DoxygenMemberGroup(o, 'Adding rows'): + with Public(o): + o( + rf''' + // ------ push_back() -------------------------------------------------------------------------- + + {doxygen('@brief Adds a new row at the end of the table.')} + SOAGEN_CPP20_CONSTEXPR + {self.name}& push_back({", ".join(lvalue_param_list)}) // + noexcept(table_traits::push_back_is_nothrow) // + {{ + table_.emplace_back({", ".join(lvalue_forward_list)}); + return *this; + }} + + {doxygen('@brief Adds a new row at the end of the table (rvalue overload).')} + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = table_traits::rvalues_are_distinct) + SOAGEN_CPP20_CONSTEXPR + {self.name}& push_back({", ".join(rvalue_param_list)}) // + noexcept(table_traits::rvalue_push_back_is_nothrow) // + {{ + table_.emplace_back({", ".join(rvalue_forward_list)}); + return *this; + }} + + // ------ emplace_back() ----------------------------------------------------------------------- + + {doxygen('@brief Constructs a new row directly in-place at the end of the table.')} + SOAGEN_CONSTRAINED_TEMPLATE((table_traits::row_constructible_from<{", ".join(template_params)}>), // + {", ".join(template_type_list)}) // + SOAGEN_CPP20_CONSTEXPR + {self.name}& emplace_back({", ".join(template_param_list)}) // + noexcept(table_traits::emplace_back_is_nothrow) // + {{ + table_.emplace_back({", ".join(template_forward_list)}); + return *this; + }} + + {doxygen('@brief Constructs a new row directly in-place at the end of the table by unpacking a tuple-like object.')} + SOAGEN_CONSTRAINED_TEMPLATE(table_traits::row_constructible_from, typename Tuple) + SOAGEN_CPP20_CONSTEXPR + {self.name}& emplace_back(Tuple&& tuple_) // + noexcept(table_traits::emplace_back_is_nothrow) // + {{ + table_.emplace_back(static_cast(tuple_)); + return *this; + }} + + ''' + ) + + with DoxygenMemberGroup( + o, + 'Inserting rows', + availability=r'These overloads are only available when all the column types are move/copy-constructible and move/copy-assignable.', + ): + with Private(o): + o( + r''' + static constexpr bool can_insert_ = table_traits::all_move_or_copy_constructible + && table_traits::all_move_or_copy_assignable; + + static constexpr bool can_insert_rvalues_ = can_insert_ && table_traits::rvalues_are_distinct; + ''' + ) + + with Public(o): + o( + rf''' + + // ------ insert(size_type) -------------------------------------------------------------------- + + {doxygen("""@brief Inserts a new row at an arbitrary position in the table. + + @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable.""")} + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = can_insert_) // + SOAGEN_CPP20_CONSTEXPR + SOAGEN_ENABLE_IF_T({self.name}&, sfinae) insert(size_type index_, {", ".join(lvalue_param_list)}) // + noexcept(table_traits::insert_is_nothrow) // + {{ + table_.emplace(index_, {", ".join(lvalue_forward_list)}); + return *this; + }} + + {doxygen("""@brief Inserts a new row at an arbitrary position in the table (rvalue overload). + + @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable.""")} + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = can_insert_rvalues_) // + SOAGEN_CPP20_CONSTEXPR + {self.name}& insert(SOAGEN_ENABLE_IF_T(size_type, sfinae) index_, {", ".join(rvalue_param_list)}) // + noexcept(table_traits::insert_is_nothrow) // + {{ + table_.emplace(index_, {", ".join(rvalue_forward_list)}); + return *this; + }} + + + // ------ insert(iterator) --------------------------------------------------------------------- + + {doxygen("""@brief Inserts a new row at an arbitrary position in the table. + + @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable.""")} + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = can_insert_) // + SOAGEN_CPP20_CONSTEXPR + SOAGEN_ENABLE_IF_T(iterator, sfinae) insert(iterator iter_, {", ".join(lvalue_param_list)}) // + noexcept(table_traits::insert_is_nothrow) // + {{ + table_.emplace(static_cast(iter_), {", ".join(lvalue_forward_list)}); + return iter_; + }} + + {doxygen("""@brief Inserts a new row at an arbitrary position in the table. + + @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable.""")} + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = can_insert_) // + SOAGEN_CPP20_CONSTEXPR + SOAGEN_ENABLE_IF_T(const_iterator, sfinae) insert(const_iterator iter_, {", ".join(lvalue_param_list)}) // + noexcept(table_traits::insert_is_nothrow) // + {{ + table_.emplace(static_cast(iter_), {", ".join(lvalue_forward_list)}); + return iter_; + }} + + {doxygen("""@brief Inserts a new row at an arbitrary position in the table (rvalue overload). + + @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable.""")} + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = can_insert_rvalues_) // + SOAGEN_CPP20_CONSTEXPR + iterator insert(SOAGEN_ENABLE_IF_T(iterator, sfinae) iter_, {", ".join(rvalue_param_list)}) // + noexcept(table_traits::insert_is_nothrow) // + {{ + table_.emplace(static_cast(iter_), {", ".join(rvalue_forward_list)}); + return iter_; + }} + + {doxygen("""@brief Inserts a new row at an arbitrary position in the table (rvalue overload). + + @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable.""")} + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = can_insert_rvalues_) // + SOAGEN_CPP20_CONSTEXPR + const_iterator insert(SOAGEN_ENABLE_IF_T(const_iterator, sfinae) iter_, {", ".join(rvalue_param_list)}) // + noexcept(table_traits::insert_is_nothrow) // + {{ + table_.emplace(static_cast(iter_), {", ".join(rvalue_forward_list)}); + return iter_; + }} + + // ------ emplace(size_type) ------------------------------------------------------------------- + + {doxygen("""@brief Constructs a new row directly in-place at an arbitrary position in the table. + + @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable.""")} + SOAGEN_CONSTRAINED_TEMPLATE(sfinae, {", ".join(template_type_list)} + SOAGEN_HIDDEN_PARAM(bool sfinae = table_traits::row_constructible_from<{", ".join(template_params)}> && can_insert_)) // + SOAGEN_CPP20_CONSTEXPR + SOAGEN_ENABLE_IF_T({self.name}&, sfinae) emplace(size_type index_, {", ".join(template_param_list)}) // + noexcept(table_traits::emplace_is_nothrow) // + {{ + table_.emplace(index_, {", ".join(template_forward_list)}); + return *this; + }} + + {doxygen("""@brief Constructs a new row directly in-place at an arbitrary position in the table by unpacking a tuple-like object. + + @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable.""")} + SOAGEN_CONSTRAINED_TEMPLATE(sfinae, typename Tuple + SOAGEN_HIDDEN_PARAM(bool sfinae = table_traits::row_constructible_from && can_insert_)) // + SOAGEN_CPP20_CONSTEXPR + {self.name}& emplace(SOAGEN_ENABLE_IF_T(size_type, sfinae) index_, Tuple&& tuple_) // + noexcept(table_traits::emplace_is_nothrow) // + {{ + table_.emplace(index_, static_cast(tuple_)); + return *this; + }} + + // ------ emplace(iterator) -------------------------------------------------------------------- + + {doxygen("""@brief Constructs a new row directly in-place at an arbitrary position in the table. + + @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable.""")} + SOAGEN_CONSTRAINED_TEMPLATE(sfinae, {", ".join(template_type_list)} + SOAGEN_HIDDEN_PARAM(bool sfinae = table_traits::row_constructible_from<{", ".join(template_params)}> && can_insert_)) // + SOAGEN_CPP20_CONSTEXPR + SOAGEN_ENABLE_IF_T(iterator, sfinae) emplace(iterator iter_, {", ".join(template_param_list)}) // + noexcept(table_traits::emplace_is_nothrow) // + {{ + table_.emplace(static_cast(iter_), {", ".join(template_forward_list)}); + return iter_; + }} + + {doxygen("""@brief Constructs a new row directly in-place at an arbitrary position in the table by unpacking a tuple-like object. + + @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable.""")} + SOAGEN_CONSTRAINED_TEMPLATE(sfinae, typename Tuple + SOAGEN_HIDDEN_PARAM(bool sfinae = table_traits::row_constructible_from && can_insert_)) // + SOAGEN_CPP20_CONSTEXPR + iterator emplace(SOAGEN_ENABLE_IF_T(iterator, sfinae) iter_, Tuple&& tuple_) // + noexcept(table_traits::emplace_is_nothrow) // + {{ + table_.emplace(static_cast(iter_), static_cast(tuple_)); + return iter_; + }} + + {doxygen("""@brief Constructs a new row directly in-place at an arbitrary position in the table. + + @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable.""")} + SOAGEN_CONSTRAINED_TEMPLATE(sfinae, {", ".join(template_type_list)} + SOAGEN_HIDDEN_PARAM(bool sfinae = table_traits::row_constructible_from<{", ".join(template_params)}> && can_insert_)) // + SOAGEN_CPP20_CONSTEXPR + SOAGEN_ENABLE_IF_T(const_iterator, sfinae) emplace(const_iterator iter_, {", ".join(template_param_list)}) // + noexcept(table_traits::emplace_is_nothrow) // + {{ + table_.emplace(static_cast(iter_), {", ".join(template_forward_list)}); + return iter_; + }} + + {doxygen("""@brief Constructs a new row directly in-place at an arbitrary position in the table by unpacking a tuple-like object. + + @availability This overload is only available when all the column types are move/copy-constructible and move/copy-assignable.""")} + SOAGEN_CONSTRAINED_TEMPLATE(sfinae, typename Tuple + SOAGEN_HIDDEN_PARAM(bool sfinae = table_traits::row_constructible_from && can_insert_)) // + SOAGEN_CPP20_CONSTEXPR + const_iterator emplace(SOAGEN_ENABLE_IF_T(const_iterator, sfinae) iter_, Tuple&& tuple_) // + noexcept(table_traits::emplace_is_nothrow) // + {{ + table_.emplace(static_cast(iter_), static_cast(tuple_)); + return iter_; + }} + + ''' + ) with DoxygenMemberGroup(o, 'Columns'): with Public(o): diff --git a/tests/employees.hpp b/tests/employees.hpp index 0f27a38..48abae3 100644 --- a/tests/employees.hpp +++ b/tests/employees.hpp @@ -256,61 +256,61 @@ namespace tests return table_; } - template > + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = soagen::has_erase_member) SOAGEN_ALWAYS_INLINE - SOAGEN_CPP20_CONSTEXPR // - std::enable_if_t erase(size_type pos) // - noexcept(soagen::has_nothrow_erase_member) + SOAGEN_CPP20_CONSTEXPR // + std::enable_if_t erase(size_type pos) // + noexcept(soagen::has_nothrow_erase_member) // { table_.erase(pos); return *this; } - template > + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = soagen::has_unordered_erase_member) SOAGEN_ALWAYS_INLINE SOAGEN_CPP20_CONSTEXPR // std::enable_if_t> unordered_erase(size_type pos) // - noexcept(soagen::has_nothrow_unordered_erase_member) + noexcept(soagen::has_nothrow_unordered_erase_member) // { return table_.unordered_erase(pos); } - template > + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = soagen::has_erase_member) SOAGEN_ALWAYS_INLINE SOAGEN_CPP20_CONSTEXPR - std::enable_if_t erase(iterator pos) // - noexcept(soagen::has_nothrow_erase_member) + std::enable_if_t erase(iterator pos) // + noexcept(soagen::has_nothrow_erase_member) // { table_.erase(static_cast(pos)); return pos; } - template > + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = soagen::has_unordered_erase_member) SOAGEN_ALWAYS_INLINE SOAGEN_CPP20_CONSTEXPR std::enable_if_t> unordered_erase(iterator pos) // - noexcept(soagen::has_nothrow_unordered_erase_member) + noexcept(soagen::has_nothrow_unordered_erase_member) // { if (auto moved_pos = table_.unordered_erase(static_cast(pos)); moved_pos) return iterator{ *this, static_cast(*moved_pos) }; return {}; } - template > + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = soagen::has_erase_member) SOAGEN_ALWAYS_INLINE SOAGEN_CPP20_CONSTEXPR std::enable_if_t erase(const_iterator pos) // - noexcept(soagen::has_nothrow_erase_member) + noexcept(soagen::has_nothrow_erase_member) // { table_.erase(static_cast(pos)); return pos; } - template > + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = soagen::has_unordered_erase_member) SOAGEN_ALWAYS_INLINE SOAGEN_CPP20_CONSTEXPR std::enable_if_t> unordered_erase(const_iterator pos) // - noexcept(soagen::has_nothrow_unordered_erase_member) + noexcept(soagen::has_nothrow_unordered_erase_member) // { if (auto moved_pos = table_.unordered_erase(static_cast(pos)); moved_pos) return const_iterator{ *this, static_cast(*moved_pos) }; @@ -328,6 +328,8 @@ namespace tests return *this; } + // ------ push_back() -------------------------------------------------------------------------- + SOAGEN_CPP20_CONSTEXPR employees& push_back(column_traits<0>::param_type name, column_traits<1>::param_type id, @@ -344,15 +346,14 @@ namespace tests return *this; } - template + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = table_traits::rvalues_are_distinct) SOAGEN_CPP20_CONSTEXPR - employees& push_back(std::enable_if_t::rvalue_type> name, + employees& push_back(column_traits<0>::rvalue_type name, column_traits<1>::rvalue_type id, column_traits<2>::rvalue_type date_of_birth, column_traits<3>::rvalue_type salary, column_traits<4>::rvalue_type tag = nullptr) // noexcept(table_traits::rvalue_push_back_is_nothrow) // - SOAGEN_REQUIRES(table_traits::rvalues_are_distinct) // { table_.emplace_back(static_cast::rvalue_forward_type>(name), static_cast::rvalue_forward_type>(id), @@ -362,13 +363,15 @@ namespace tests return *this; } - template ::default_emplace_type, - std::enable_if_t, - int> = 0> + // ------ emplace_back() ----------------------------------------------------------------------- + + SOAGEN_CONSTRAINED_TEMPLATE( + (table_traits::row_constructible_from), // + typename Name, + typename Id, + typename DateOfBirth, + typename Salary, + typename Tag = column_traits<4>::default_emplace_type) // SOAGEN_CPP20_CONSTEXPR employees& emplace_back(Name&& name, Id&& id, @@ -376,7 +379,6 @@ namespace tests Salary&& salary, Tag&& tag = nullptr) // noexcept(table_traits::emplace_back_is_nothrow) // - SOAGEN_REQUIRES(table_traits::row_constructible_from) // { table_.emplace_back(static_cast(name), static_cast(id), @@ -386,27 +388,33 @@ namespace tests return *this; } - template , int> = 0> + SOAGEN_CONSTRAINED_TEMPLATE(table_traits::row_constructible_from, typename Tuple) SOAGEN_CPP20_CONSTEXPR employees& emplace_back(Tuple&& tuple_) // noexcept(table_traits::emplace_back_is_nothrow) // - SOAGEN_REQUIRES(table_traits::row_constructible_from) // { table_.emplace_back(static_cast(tuple_)); return *this; } - template + private: + static constexpr bool can_insert_ = + table_traits::all_move_or_copy_constructible && table_traits::all_move_or_copy_assignable; + + static constexpr bool can_insert_rvalues_ = can_insert_ && table_traits::rvalues_are_distinct; + + public: + // ------ insert(size_type) -------------------------------------------------------------------- + + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = can_insert_) // SOAGEN_CPP20_CONSTEXPR std::enable_if_t insert(size_type index_, column_traits<0>::param_type name, column_traits<1>::param_type id, column_traits<2>::param_type date_of_birth, column_traits<3>::param_type salary, - column_traits<4>::param_type tag = nullptr) // - noexcept(table_traits::insert_is_nothrow) // - SOAGEN_REQUIRES(table_traits::all_move_or_copy_constructible&& table_traits::all_move_or_copy_assignable) // + column_traits<4>::param_type tag = nullptr) // + noexcept(table_traits::insert_is_nothrow) // { table_.emplace(index_, static_cast::param_forward_type>(name), @@ -417,17 +425,36 @@ namespace tests return *this; } - template + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = can_insert_rvalues_) // + SOAGEN_CPP20_CONSTEXPR + employees& insert(std::enable_if_t index_, + column_traits<0>::rvalue_type name, + column_traits<1>::rvalue_type id, + column_traits<2>::rvalue_type date_of_birth, + column_traits<3>::rvalue_type salary, + column_traits<4>::rvalue_type tag = nullptr) // + noexcept(table_traits::insert_is_nothrow) // + { + table_.emplace(index_, + static_cast::rvalue_forward_type>(name), + static_cast::rvalue_forward_type>(id), + static_cast::rvalue_forward_type>(date_of_birth), + static_cast::rvalue_forward_type>(salary), + static_cast::rvalue_forward_type>(tag)); + return *this; + } + + // ------ insert(iterator) --------------------------------------------------------------------- + + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = can_insert_) // SOAGEN_CPP20_CONSTEXPR std::enable_if_t insert(iterator iter_, column_traits<0>::param_type name, column_traits<1>::param_type id, column_traits<2>::param_type date_of_birth, column_traits<3>::param_type salary, - column_traits<4>::param_type tag = nullptr) // - noexcept(table_traits::insert_is_nothrow) // - SOAGEN_REQUIRES(table_traits::all_move_or_copy_constructible&& table_traits::all_move_or_copy_assignable) // + column_traits<4>::param_type tag = nullptr) // + noexcept(table_traits::insert_is_nothrow) // { table_.emplace(static_cast(iter_), static_cast::param_forward_type>(name), @@ -438,17 +465,15 @@ namespace tests return iter_; } - template + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = can_insert_) // SOAGEN_CPP20_CONSTEXPR std::enable_if_t insert(const_iterator iter_, column_traits<0>::param_type name, column_traits<1>::param_type id, column_traits<2>::param_type date_of_birth, column_traits<3>::param_type salary, - column_traits<4>::param_type tag = nullptr) // - noexcept(table_traits::insert_is_nothrow) // - SOAGEN_REQUIRES(table_traits::all_move_or_copy_constructible&& table_traits::all_move_or_copy_assignable) // + column_traits<4>::param_type tag = nullptr) // + noexcept(table_traits::insert_is_nothrow) // { table_.emplace(static_cast(iter_), static_cast::param_forward_type>(name), @@ -459,40 +484,15 @@ namespace tests return iter_; } - template - SOAGEN_CPP20_CONSTEXPR - employees& insert(std::enable_if_t index_, - column_traits<0>::rvalue_type name, - column_traits<1>::rvalue_type id, - column_traits<2>::rvalue_type date_of_birth, - column_traits<3>::rvalue_type salary, - column_traits<4>::rvalue_type tag = nullptr) // - noexcept(table_traits::rvalue_insert_is_nothrow) // - SOAGEN_REQUIRES(table_traits::rvalues_are_distinct&& table_traits::all_move_or_copy_constructible&& - table_traits::all_move_or_copy_assignable) // - { - table_.emplace(index_, - static_cast::rvalue_forward_type>(name), - static_cast::rvalue_forward_type>(id), - static_cast::rvalue_forward_type>(date_of_birth), - static_cast::rvalue_forward_type>(salary), - static_cast::rvalue_forward_type>(tag)); - return *this; - } - - template + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = can_insert_rvalues_) // SOAGEN_CPP20_CONSTEXPR iterator insert(std::enable_if_t iter_, column_traits<0>::rvalue_type name, column_traits<1>::rvalue_type id, column_traits<2>::rvalue_type date_of_birth, column_traits<3>::rvalue_type salary, - column_traits<4>::rvalue_type tag = nullptr) // - noexcept(table_traits::rvalue_insert_is_nothrow) // - SOAGEN_REQUIRES(table_traits::rvalues_are_distinct&& table_traits::all_move_or_copy_constructible&& - table_traits::all_move_or_copy_assignable) // + column_traits<4>::rvalue_type tag = nullptr) // + noexcept(table_traits::insert_is_nothrow) // { table_.emplace(static_cast(iter_), static_cast::rvalue_forward_type>(name), @@ -503,8 +503,7 @@ namespace tests return iter_; } - template + SOAGEN_HIDDEN_CONSTRAINT(sfinae, bool sfinae = can_insert_rvalues_) // SOAGEN_CPP20_CONSTEXPR const_iterator insert(std::enable_if_t iter_, column_traits<0>::rvalue_type name, @@ -512,9 +511,7 @@ namespace tests column_traits<2>::rvalue_type date_of_birth, column_traits<3>::rvalue_type salary, column_traits<4>::rvalue_type tag = nullptr) // - noexcept(table_traits::rvalue_insert_is_nothrow) // - SOAGEN_REQUIRES(table_traits::rvalues_are_distinct&& table_traits::all_move_or_copy_constructible&& - table_traits::all_move_or_copy_assignable) // + noexcept(table_traits::insert_is_nothrow) // { table_.emplace(static_cast(iter_), static_cast::rvalue_forward_type>(name), @@ -525,25 +522,25 @@ namespace tests return iter_; } - template < + // ------ emplace(size_type) ------------------------------------------------------------------- + + SOAGEN_CONSTRAINED_TEMPLATE( + sfinae, typename Name, typename Id, typename DateOfBirth, typename Salary, - typename Tag = column_traits<4>::default_emplace_type, - std::enable_if_t<(table_traits::all_move_or_copy_constructible && table_traits::all_move_or_copy_assignable - && table_traits::row_constructible_from), - int> = 0> + typename Tag = column_traits<4>::default_emplace_type, + bool sfinae = table_traits::row_constructible_from + && can_insert_) // SOAGEN_CPP20_CONSTEXPR - employees& emplace(size_type index_, - Name&& name, - Id&& id, - DateOfBirth&& date_of_birth, - Salary&& salary, - Tag&& tag = nullptr) // + std::enable_if_t emplace(size_type index_, + Name&& name, + Id&& id, + DateOfBirth&& date_of_birth, + Salary&& salary, + Tag&& tag = nullptr) // noexcept(table_traits::emplace_is_nothrow) // - SOAGEN_REQUIRES(table_traits::all_move_or_copy_constructible&& table_traits::all_move_or_copy_assignable&& - table_traits::row_constructible_from) // { table_.emplace(index_, static_cast(name), @@ -554,25 +551,36 @@ namespace tests return *this; } - template < + SOAGEN_CONSTRAINED_TEMPLATE(sfinae, + typename Tuple, + bool sfinae = table_traits::row_constructible_from && can_insert_) // + SOAGEN_CPP20_CONSTEXPR + employees& emplace(std::enable_if_t index_, Tuple&& tuple_) // + noexcept(table_traits::emplace_is_nothrow) // + { + table_.emplace(index_, static_cast(tuple_)); + return *this; + } + + // ------ emplace(iterator) -------------------------------------------------------------------- + + SOAGEN_CONSTRAINED_TEMPLATE( + sfinae, typename Name, typename Id, typename DateOfBirth, typename Salary, - typename Tag = column_traits<4>::default_emplace_type, - std::enable_if_t<(table_traits::all_move_or_copy_constructible && table_traits::all_move_or_copy_assignable - && table_traits::row_constructible_from), - int> = 0> + typename Tag = column_traits<4>::default_emplace_type, + bool sfinae = table_traits::row_constructible_from + && can_insert_) // SOAGEN_CPP20_CONSTEXPR - iterator emplace(iterator iter_, - Name&& name, - Id&& id, - DateOfBirth&& date_of_birth, - Salary&& salary, - Tag&& tag = nullptr) // + std::enable_if_t emplace(iterator iter_, + Name&& name, + Id&& id, + DateOfBirth&& date_of_birth, + Salary&& salary, + Tag&& tag = nullptr) // noexcept(table_traits::emplace_is_nothrow) // - SOAGEN_REQUIRES(table_traits::all_move_or_copy_constructible&& table_traits::all_move_or_copy_assignable&& - table_traits::row_constructible_from) // { table_.emplace(static_cast(iter_), static_cast(name), @@ -583,25 +591,34 @@ namespace tests return iter_; } - template < + SOAGEN_CONSTRAINED_TEMPLATE(sfinae, + typename Tuple, + bool sfinae = table_traits::row_constructible_from && can_insert_) // + SOAGEN_CPP20_CONSTEXPR + iterator emplace(std::enable_if_t iter_, Tuple&& tuple_) // + noexcept(table_traits::emplace_is_nothrow) // + { + table_.emplace(static_cast(iter_), static_cast(tuple_)); + return iter_; + } + + SOAGEN_CONSTRAINED_TEMPLATE( + sfinae, typename Name, typename Id, typename DateOfBirth, typename Salary, - typename Tag = column_traits<4>::default_emplace_type, - std::enable_if_t<(table_traits::all_move_or_copy_constructible && table_traits::all_move_or_copy_assignable - && table_traits::row_constructible_from), - int> = 0> + typename Tag = column_traits<4>::default_emplace_type, + bool sfinae = table_traits::row_constructible_from + && can_insert_) // SOAGEN_CPP20_CONSTEXPR - const_iterator emplace(const_iterator iter_, - Name&& name, - Id&& id, - DateOfBirth&& date_of_birth, - Salary&& salary, - Tag&& tag = nullptr) // + std::enable_if_t emplace(const_iterator iter_, + Name&& name, + Id&& id, + DateOfBirth&& date_of_birth, + Salary&& salary, + Tag&& tag = nullptr) // noexcept(table_traits::emplace_is_nothrow) // - SOAGEN_REQUIRES(table_traits::all_move_or_copy_constructible&& table_traits::all_move_or_copy_assignable&& - table_traits::row_constructible_from) // { table_.emplace(static_cast(iter_), static_cast(name), @@ -612,49 +629,12 @@ namespace tests return iter_; } - template - && table_traits::all_move_or_copy_constructible - && table_traits::all_move_or_copy_assignable), - int> = 0> - SOAGEN_CPP20_CONSTEXPR - employees& emplace(size_type index_, Tuple&& tuple_) // - noexcept(table_traits::emplace_is_nothrow) // - SOAGEN_REQUIRES( - table_traits::row_constructible_from&& table_traits::all_move_or_copy_constructible&& - table_traits::all_move_or_copy_assignable) // - { - table_.emplace(index_, static_cast(tuple_)); - return *this; - } - - template - && table_traits::all_move_or_copy_constructible - && table_traits::all_move_or_copy_assignable), - int> = 0> - SOAGEN_CPP20_CONSTEXPR - iterator emplace(iterator iter_, Tuple&& tuple_) // - noexcept(table_traits::emplace_is_nothrow) // - SOAGEN_REQUIRES( - table_traits::row_constructible_from&& table_traits::all_move_or_copy_constructible&& - table_traits::all_move_or_copy_assignable) // - { - table_.emplace(static_cast(iter_), static_cast(tuple_)); - return iter_; - } - - template - && table_traits::all_move_or_copy_constructible - && table_traits::all_move_or_copy_assignable), - int> = 0> + SOAGEN_CONSTRAINED_TEMPLATE(sfinae, + typename Tuple, + bool sfinae = table_traits::row_constructible_from && can_insert_) // SOAGEN_CPP20_CONSTEXPR - const_iterator emplace(const_iterator iter_, Tuple&& tuple_) // - noexcept(table_traits::emplace_is_nothrow) // - SOAGEN_REQUIRES( - table_traits::row_constructible_from&& table_traits::all_move_or_copy_constructible&& - table_traits::all_move_or_copy_assignable) // + const_iterator emplace(std::enable_if_t iter_, Tuple&& tuple_) // + noexcept(table_traits::emplace_is_nothrow) // { table_.emplace(static_cast(iter_), static_cast(tuple_)); return iter_;