diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2b34d9c..9dfc09b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
# Changelog
+## v0.1.2
+
+- Minor refactors.
+
## v0.1.1
- Minor refactors.
diff --git a/docs/pages/intro.md b/docs/pages/intro.md
index 5df4f6c..c7640da 100644
--- a/docs/pages/intro.md
+++ b/docs/pages/intro.md
@@ -240,7 +240,7 @@ you move on to read about **soagen**, here's some resources:
I'd to present my solution to the problems of working with Structure-of-Arrays in C++: **soagen**. Soagen is fundamentally two things:
-1. [`soagen`], a command-line code utility for generating `std::vector`-like SoA containers, and
+1. [`soagen`], a command-line code utility for generating bespoke `std::vector`-like SoA containers, and
2. [`soagen.hpp`], a single-header backing library upon which the generated code depends.
Typically you only need to use the command-line tool [`soagen`], and don't need to know anything about [`soagen.hpp`]
@@ -778,7 +778,7 @@ auto&& column_0 = r.column<0>(); // id
auto&& column_3 = r.column<3>(); // orient
```
-Finally, now that we understand rows, I can reveal that you can _also_ use them with `push_back()` and `insert()`:
+Finally, you can use them with `push_back()` and `insert()`:
```cpp
e.push_back(e[0]); // push a copy of row[0] onto the end of the table
@@ -793,7 +793,7 @@ e.push_back(e[0]); // push a copy of row[0] onto the end of the table
@section intro_equality Equality
-If all the column types implement the named requirement [EqualityComparable] \(i.e. they have `operator==`\), then so too
+If all the column types implement the named requirement EqualityComparable \(i.e. they have `operator==`\), then so too
do your tables:
```cpp
@@ -821,7 +821,7 @@ true
false
@eout
-The same is true of rows; if all of the viewed members are [EqualityComparable], then so too are the rows:
+The same is true of rows; if all of the viewed members are EqualityComparable, then so too are the rows:
```
std::cout << (e1[0] == e2[0]) << "\n";
@@ -833,16 +833,16 @@ true
false
@eout
-@note Rows do not have to have come from a table that is entirely [EqualityComparable]; it only depends on whether or not
+@note Rows do not have to have come from a table that is entirely EqualityComparable; it only depends on whether or not
their viewed columns are. You can take a row view of only a few columns of a much larger table, and so long as the
-viewed columns are [EqualityComparable], so too is the resulting #soagen::row type.
+viewed columns are EqualityComparable, so too is the resulting #soagen::row type.
@section intro_comparison Comparison
Tables are comparable with operators `<`, `<=`, `>` and `>=` if all their column types implement the named
-requirement [LessThanComparable] \(i.e. they have `operator<`\). Comparison is done row-wise, with row members
+requirement LessThanComparable \(i.e. they have `operator<`\). Comparison is done row-wise, with row members
compared lexicographically:
```cpp
@@ -876,7 +876,7 @@ false
false
@eout
-@note Just as with [EqualityComparable], rows are [LessThanComparable] if their viewed members are, too.
+@note Just as with EqualityComparable, rows are LessThanComparable if their viewed members are, too.
It does not depend on the source table.
@@ -960,7 +960,7 @@ allocator = 'foo::fancy_allocator' # ...can also be overridden set per-struct
The only requirements of your allocator are:
-- It must properly implement the named requirement [Allocator], and
+- It must properly implement the named requirement Allocator, and
- Have a `value_type` of `char`, `unsigned char` or `std::byte`.
@subsection intro_customizing_allocators Customizing allocators for soagen
@@ -1004,7 +1004,7 @@ Soagen will choose this overload over any others if it is present.
@section intro_access_underlying_buffer Accessing the underlying buffer
Soagen allocates one contiguous buffer for the entire table. If all the column types in your table are
-[TriviallyCopyable] you'll be able to access the underlying buffer directly with `data()`, and determine it's size with
+TriviallyCopyable you'll be able to access the underlying buffer directly with `data()`, and determine it's size with
`allocation_size()`, allowing you to serialize/deserialize it directly, stream it, hash it, et cetera.
@see
@@ -1033,7 +1033,7 @@ To use a #soagen::table directly, you need to express it terms of #soagen::table
using entities = soagen::table,
soagen::column_traits,
- soagen::column_traits, 32>,
+ soagen::column_traits,
soagen::column_traits
>>;
@@ -1077,7 +1077,7 @@ Thanks!
\[p\]
I'm Mark. You might know me as the toml++ guy.
I write code. Some of it is alright. Almost all of it is C++.
-\[span class="socials"\]
+\[span class="poxy-socials"\]
\[img src="poxy/poxy-icon-github.svg" class="poxy-icon"\]
\[img src="poxy/poxy-icon-twitter.svg" class="poxy-icon"\]
\[img src="poxy/poxy-icon-email.svg" class="poxy-icon"\]
@@ -1097,8 +1097,4 @@ I write code. Some of it is alright. Almost all of it is C++.
[`unordered_erase()`]: classsoagen_1_1examples_1_1entities.html#a117807c0fbe9e2ed2fbe39c9193ff231
[`row()`]: classsoagen_1_1examples_1_1entities.html#ac24830714a0cf3a0f677b77936a79e73
[`aligned_stride`]: structsoagen_1_1table__traits.html#a7b18454ef28aa4279e1f1fc61bd15381
-[Allocator]: https://en.cppreference.com/w/cpp/named_req/Allocator
-[EqualityComparable]: https://en.cppreference.com/w/cpp/named_req/EqualityComparable
-[LessThanComparable]: https://en.cppreference.com/w/cpp/named_req/LessThanComparable
-[TriviallyCopyable]: https://en.cppreference.com/w/cpp/named_req/TriviallyCopyable
[roadmap]: https://github.com/marzer/soagen/issues/1
diff --git a/examples/entities.hpp b/examples/entities.hpp
index 25e8db9..75aac23 100644
--- a/examples/entities.hpp
+++ b/examples/entities.hpp
@@ -4,7 +4,7 @@
// See https://github.com/marzer/soagen/blob/master/LICENSE for the full license text.
// SPDX-License-Identifier: MIT
//----------------------------------------------------------------------------------------------------------------------
-// This file was generated by soagen v0.1.1 - do not modify it directly
+// This file was generated by soagen v0.1.2 - do not modify it directly
// https://marzer.github.io/soagen
//----------------------------------------------------------------------------------------------------------------------
#pragma once
@@ -54,8 +54,8 @@ SOAGEN_DISABLE_SPAM_WARNINGS;
#ifndef SOAGEN_MAKE_NAME
#define SOAGEN_MAKE_NAME(...) static_assert(true)
#endif
- #ifndef SOAGEN_MAKE_COL
- #define SOAGEN_MAKE_COL(...) static_assert(true)
+ #ifndef SOAGEN_MAKE_COLUMN
+ #define SOAGEN_MAKE_COLUMN(...) static_assert(true)
#endif
#ifndef SOAGEN_NODISCARD
#define SOAGEN_NODISCARD
@@ -120,6 +120,8 @@ SOAGEN_DISABLE_SPAM_WARNINGS;
/// @cond
+// clang-format off
+
namespace soagen::examples
{
class entities;
@@ -133,8 +135,6 @@ namespace soagen
namespace soagen::detail
{
- // clang-format off
-
#ifndef SOAGEN_NAME_id
#define SOAGEN_NAME_id
SOAGEN_MAKE_NAME(id);
@@ -155,16 +155,14 @@ namespace soagen::detail
SOAGEN_MAKE_NAME(pos);
#endif
- // clang-format on
-
template <>
struct table_traits_type_
{
using type = table_traits<
- /* id */ make_column,
- /* name */ make_column,
- /* pos */ make_column, 32>,
- /* orient */ make_column>;
+ /* id */ column_traits,
+ /* name */ column_traits,
+ /* pos */ column_traits,
+ /* orient */ column_traits>;
};
template <>
@@ -173,10 +171,10 @@ namespace soagen::detail
using type = soagen::allocator;
};
- SOAGEN_MAKE_COL(soagen::examples::entities, 0, id);
- SOAGEN_MAKE_COL(soagen::examples::entities, 1, name);
- SOAGEN_MAKE_COL(soagen::examples::entities, 2, pos);
- SOAGEN_MAKE_COL(soagen::examples::entities, 3, orient);
+ SOAGEN_MAKE_COLUMN(soagen::examples::entities, 0, id);
+ SOAGEN_MAKE_COLUMN(soagen::examples::entities, 1, name);
+ SOAGEN_MAKE_COLUMN(soagen::examples::entities, 2, pos);
+ SOAGEN_MAKE_COLUMN(soagen::examples::entities, 3, orient);
template <>
struct table_type_
@@ -185,6 +183,8 @@ namespace soagen::detail
};
}
+// clang-format on
+
/// @endcond
//----------------------------------------------------------------------------------------------------------------------
@@ -286,9 +286,9 @@ namespace soagen::examples
};
#endif
- /// @brief Gets the name of the specified column as a string.
+ /// @brief Gets the name of the specified column as a null-terminated string.
template
- static constexpr auto& column_name = soagen::detail::col_name_::value;
+ static constexpr auto& column_name = soagen::detail::column_name_::value;
private:
/// @cond
diff --git a/examples/entities.natvis b/examples/entities.natvis
index 702467f..d0a045d 100644
--- a/examples/entities.natvis
+++ b/examples/entities.natvis
@@ -1,6 +1,6 @@
diff --git a/examples/shapes.hpp b/examples/shapes.hpp
index c39c220..2aede1d 100644
--- a/examples/shapes.hpp
+++ b/examples/shapes.hpp
@@ -4,7 +4,7 @@
// See https://github.com/marzer/soagen/blob/master/LICENSE for the full license text.
// SPDX-License-Identifier: MIT
//----------------------------------------------------------------------------------------------------------------------
-// This file was generated by soagen v0.1.1 - do not modify it directly
+// This file was generated by soagen v0.1.2 - do not modify it directly
// https://marzer.github.io/soagen
//----------------------------------------------------------------------------------------------------------------------
#pragma once
@@ -53,8 +53,8 @@ SOAGEN_DISABLE_SPAM_WARNINGS;
#ifndef SOAGEN_MAKE_NAME
#define SOAGEN_MAKE_NAME(...) static_assert(true)
#endif
- #ifndef SOAGEN_MAKE_COL
- #define SOAGEN_MAKE_COL(...) static_assert(true)
+ #ifndef SOAGEN_MAKE_COLUMN
+ #define SOAGEN_MAKE_COLUMN(...) static_assert(true)
#endif
#ifndef SOAGEN_NODISCARD
#define SOAGEN_NODISCARD
@@ -119,6 +119,8 @@ SOAGEN_DISABLE_SPAM_WARNINGS;
/// @cond
+// clang-format off
+
namespace soagen::examples
{
class boxes;
@@ -136,8 +138,6 @@ namespace soagen
namespace soagen::detail
{
- // clang-format off
-
#ifndef SOAGEN_NAME_center_x
#define SOAGEN_NAME_center_x
SOAGEN_MAKE_NAME(center_x);
@@ -178,19 +178,17 @@ namespace soagen::detail
SOAGEN_MAKE_NAME(radius);
#endif
- // clang-format on
-
template <>
struct table_traits_type_
{
using type = table_traits<
- /* center_x */ make_column, 32>,
- /* center_y */ make_column, 32>,
- /* center_z */ make_column, 32>,
- /* extents_x */ make_column, 32>,
- /* extents_y */ make_column, 32>,
- /* extents_z */ make_column, 32>,
- /* mass */ make_column>;
+ /* center_x */ column_traits,
+ /* center_y */ column_traits,
+ /* center_z */ column_traits,
+ /* extents_x */ column_traits,
+ /* extents_y */ column_traits,
+ /* extents_z */ column_traits,
+ /* mass */ column_traits>;
};
template <>
@@ -199,13 +197,13 @@ namespace soagen::detail
using type = soagen::allocator;
};
- SOAGEN_MAKE_COL(soagen::examples::boxes, 0, center_x);
- SOAGEN_MAKE_COL(soagen::examples::boxes, 1, center_y);
- SOAGEN_MAKE_COL(soagen::examples::boxes, 2, center_z);
- SOAGEN_MAKE_COL(soagen::examples::boxes, 3, extents_x);
- SOAGEN_MAKE_COL(soagen::examples::boxes, 4, extents_y);
- SOAGEN_MAKE_COL(soagen::examples::boxes, 5, extents_z);
- SOAGEN_MAKE_COL(soagen::examples::boxes, 6, mass);
+ SOAGEN_MAKE_COLUMN(soagen::examples::boxes, 0, center_x);
+ SOAGEN_MAKE_COLUMN(soagen::examples::boxes, 1, center_y);
+ SOAGEN_MAKE_COLUMN(soagen::examples::boxes, 2, center_z);
+ SOAGEN_MAKE_COLUMN(soagen::examples::boxes, 3, extents_x);
+ SOAGEN_MAKE_COLUMN(soagen::examples::boxes, 4, extents_y);
+ SOAGEN_MAKE_COLUMN(soagen::examples::boxes, 5, extents_z);
+ SOAGEN_MAKE_COLUMN(soagen::examples::boxes, 6, mass);
template <>
struct table_type_
@@ -217,11 +215,11 @@ namespace soagen::detail
struct table_traits_type_
{
using type = table_traits<
- /* center_x */ make_column, 32>,
- /* center_y */ make_column, 32>,
- /* center_z */ make_column, 32>,
- /* radius */ make_column, 32>,
- /* mass */ make_column>;
+ /* center_x */ column_traits,
+ /* center_y */ column_traits,
+ /* center_z */ column_traits,
+ /* radius */ column_traits,
+ /* mass */ column_traits>;
};
template <>
@@ -230,11 +228,11 @@ namespace soagen::detail
using type = soagen::allocator;
};
- SOAGEN_MAKE_COL(soagen::examples::spheres, 0, center_x);
- SOAGEN_MAKE_COL(soagen::examples::spheres, 1, center_y);
- SOAGEN_MAKE_COL(soagen::examples::spheres, 2, center_z);
- SOAGEN_MAKE_COL(soagen::examples::spheres, 3, radius);
- SOAGEN_MAKE_COL(soagen::examples::spheres, 4, mass);
+ SOAGEN_MAKE_COLUMN(soagen::examples::spheres, 0, center_x);
+ SOAGEN_MAKE_COLUMN(soagen::examples::spheres, 1, center_y);
+ SOAGEN_MAKE_COLUMN(soagen::examples::spheres, 2, center_z);
+ SOAGEN_MAKE_COLUMN(soagen::examples::spheres, 3, radius);
+ SOAGEN_MAKE_COLUMN(soagen::examples::spheres, 4, mass);
template <>
struct table_type_
@@ -243,6 +241,8 @@ namespace soagen::detail
};
}
+// clang-format on
+
/// @endcond
//----------------------------------------------------------------------------------------------------------------------
@@ -361,9 +361,9 @@ namespace soagen::examples
};
#endif
- /// @brief Gets the name of the specified column as a string.
+ /// @brief Gets the name of the specified column as a null-terminated string.
template
- static constexpr auto& column_name = soagen::detail::col_name_::value;
+ static constexpr auto& column_name = soagen::detail::column_name_::value;
static constexpr float default_mass = 2.0;
@@ -1703,9 +1703,9 @@ namespace soagen::examples
};
#endif
- /// @brief Gets the name of the specified column as a string.
+ /// @brief Gets the name of the specified column as a null-terminated string.
template
- static constexpr auto& column_name = soagen::detail::col_name_::value;
+ static constexpr auto& column_name = soagen::detail::column_name_::value;
static constexpr float default_mass = 1.0;
diff --git a/examples/shapes.natvis b/examples/shapes.natvis
index fdc29a2..685215f 100644
--- a/examples/shapes.natvis
+++ b/examples/shapes.natvis
@@ -1,6 +1,6 @@
diff --git a/src/soagen/config.py b/src/soagen/config.py
index d9665c1..d4ef337 100644
--- a/src/soagen/config.py
+++ b/src/soagen/config.py
@@ -65,7 +65,7 @@ def __init__(self, path):
# namespace
if self.namespace:
- if self.namespace in (r'std', r'soagen') or self.namespace.startswith(r'std::'):
+ if self.namespace in (r'std', r'soagen', r'soagen::detail') or self.namespace.startswith(r'std::'):
raise SchemaError(rf"namespace: '{self.namespace}' is reserved", None)
self.meta.push('namespace', self.namespace)
self.meta.push('namespace::name', self.namespace)
@@ -79,7 +79,6 @@ def __init__(self, path):
self.meta.push('namespace::start', '')
self.meta.push('namespace::end', '')
self.meta.push('namespace::scope', '')
- self.namespace_macro_alias = re.sub(r'__+', '_', self.namespace.upper().replace('::', '_'))
# injectors for the 'all_X' sections
self.all_structs = StructInjector(self, self.all_structs)
diff --git a/src/soagen/header_file.py b/src/soagen/header_file.py
index ef376c9..ef3419a 100644
--- a/src/soagen/header_file.py
+++ b/src/soagen/header_file.py
@@ -151,8 +151,8 @@ def write(self, o: Writer):
#ifndef SOAGEN_MAKE_NAME
#define SOAGEN_MAKE_NAME(...) static_assert(true)
#endif
- #ifndef SOAGEN_MAKE_COL
- #define SOAGEN_MAKE_COL(...) static_assert(true)
+ #ifndef SOAGEN_MAKE_COLUMN
+ #define SOAGEN_MAKE_COLUMN(...) static_assert(true)
#endif
#ifndef SOAGEN_NODISCARD
#define SOAGEN_NODISCARD
@@ -222,7 +222,7 @@ def write(self, o: Writer):
//{"-"*(120 - o.indent_width - 2)}
'''
)
- with HiddenFromDoxygen(o):
+ with HiddenFromDoxygen(o), ClangFormatOff(o):
with Namespace(o, self.config.namespace):
for struct in self.structs:
with MetaScope(self.config.meta_stack, struct.meta):
@@ -239,18 +239,17 @@ def write(self, o: Writer):
for col in struct.columns:
names.add(col.name)
names = sorted(list(names))
- with ClangFormatOff(o):
- for name in names:
- sanitized_name = name.replace('::', '_')
- pp_define = rf'SOAGEN_NAME_{sanitized_name}'
- o(
- rf'''
- #ifndef {pp_define}
- #define {pp_define}
- SOAGEN_MAKE_NAME({name});
- #endif
- '''
- )
+ for name in names:
+ sanitized_name = name.replace('::', '_')
+ pp_define = rf'SOAGEN_NAME_{sanitized_name}'
+ o(
+ rf'''
+ #ifndef {pp_define}
+ #define {pp_define}
+ SOAGEN_MAKE_NAME({name});
+ #endif
+ '''
+ )
for struct in self.structs:
with MetaScope(self.config.meta_stack, struct.meta):
struct.write_soagen_detail_specializations(o)
diff --git a/src/soagen/hpp/column_traits.hpp b/src/soagen/hpp/column_traits.hpp
index acf2ce6..8f24cdc 100644
--- a/src/soagen/hpp/column_traits.hpp
+++ b/src/soagen/hpp/column_traits.hpp
@@ -729,15 +729,15 @@ namespace soagen
{
/// @brief Traits for a single column of a table.
/// @tparam ValueType The column's value type.
- /// @tparam ParamType The type used for the column in function parameter contexts (e.g. push_back()).
/// @tparam Align The minimum memory alignment of the first element in the column.
+ /// @tparam ParamType The type used for the column in function parameter contexts (e.g. push_back()).
///
/// @attention This class is an implementation detail for the soagen-generated Structure-of-arrays classes.
/// You don't need to know anything about it unless you are implementing your own SoA machinery
/// without using the soagen generator.
template ,
- size_t Align = alignof(ValueType)>
+ size_t Align = alignof(ValueType),
+ typename ParamType = soagen::param_type>
struct SOAGEN_EMPTY_BASES column_traits //
SOAGEN_HIDDEN_BASE(public detail::column_traits_base>)
{
@@ -757,6 +757,23 @@ namespace soagen
static_assert(alignof(value_type) == alignof(typename base_traits::storage_type));
static_assert(sizeof(value_type) == sizeof(typename base_traits::storage_type));
+ /// @brief The minimum memory alignment of the first element in the column.
+ ///
+ /// @note This is *not* the alignment of each individual element! That is always `alignof(value_type)`.
+ /// This value is referring to the alignment of the allocation for the entire column's buffer region.
+ static constexpr size_t alignment = max(Align, alignof(value_type));
+ static_assert(has_single_bit(alignment), "column alignment must be a power of two");
+
+ /// @brief The amount of elements to advance to maintain the requested #alignment for this column.
+ ///
+ /// @details The stride size you need to use when iterating through elements of this column such that
+ /// the starting element for each batch would have the same memory alignment as the value specified
+ /// for #alignment.
+ ///
+ /// @note Typically you can ignore this; column elements are always aligned correctly according to their
+ /// type. This is for over-alignment scenarios where you need to do things in batches (e.g. SIMD).
+ static constexpr size_t aligned_stride = lcm(alignment, sizeof(value_type)) / sizeof(value_type);
+
/// @brief The type used for the column in lvalue function parameter contexts (e.g. `push_back(const &)`).
using param_type = ParamType;
static_assert(!std::is_void_v, "column param_type may not be void");
@@ -776,31 +793,14 @@ namespace soagen
/// @brief The default type for `emplace()` and `emplace_back()` for columns that have a `default` value.
using default_emplace_type = make_cref;
-
- /// @brief The minimum memory alignment of the first element in the column.
- ///
- /// @note This is *not* the alignment of each individual element! That is always `alignof(value_type)`.
- /// This value is referring to the alignment of the allocation for the entire column's buffer region.
- static constexpr size_t alignment = max(Align, alignof(value_type));
- static_assert(has_single_bit(alignment), "column alignment must be a power of two");
-
- /// @brief The amount of elements to advance to maintain the requested #alignment for this column.
- ///
- /// @details The stride size you need to use when iterating through elements of this column such that
- /// the starting element for each batch would have the same memory alignment as the value specified
- /// for #alignment.
- ///
- /// @note Typically you can ignore this; column elements are always aligned correctly according to their
- /// type. This is for over-alignment scenarios where you need to do things in batches (e.g. SIMD).
- static constexpr size_t aligned_stride = lcm(alignment, sizeof(value_type)) / sizeof(value_type);
};
/// @brief True if `T` is an instance of #soagen::column_traits.
template
inline constexpr bool is_column_traits = POXY_IMPLEMENTATION_DETAIL(false);
/// @cond
- template
- inline constexpr bool is_column_traits> = true;
+ template
+ inline constexpr bool is_column_traits> = true;
template
inline constexpr bool is_column_traits> = true;
template
@@ -818,23 +818,16 @@ namespace soagen::detail
template
struct to_base_traits_;
- template
- struct to_base_traits_>
+ template
+ struct to_base_traits_>
{
using type = column_traits_base>;
- static_assert(std::is_base_of_v>);
+ static_assert(std::is_base_of_v>);
};
template
using to_base_traits = typename to_base_traits_::type;
-
- template ,
- size_t Align = alignof(ValueType)>
- using make_column = soagen::column_traits;
}
/// @endcond
diff --git a/src/soagen/hpp/generated/version.hpp b/src/soagen/hpp/generated/version.hpp
index d2df0b1..be8a4e7 100644
--- a/src/soagen/hpp/generated/version.hpp
+++ b/src/soagen/hpp/generated/version.hpp
@@ -6,5 +6,5 @@
#define SOAGEN_VERSION_MAJOR 0
#define SOAGEN_VERSION_MINOR 1
-#define SOAGEN_VERSION_PATCH 1
-#define SOAGEN_VERSION_STRING "0.1.1"
+#define SOAGEN_VERSION_PATCH 2
+#define SOAGEN_VERSION_STRING "0.1.2"
diff --git a/src/soagen/hpp/iterator.hpp b/src/soagen/hpp/iterator.hpp
index aa75aab..9eba59e 100644
--- a/src/soagen/hpp/iterator.hpp
+++ b/src/soagen/hpp/iterator.hpp
@@ -91,7 +91,7 @@ namespace soagen
}
/// @endcond
- /// @brief LegacyRandomAccessIterator for soagen-generated table types.
+ /// @brief RandomAccessIterator for soagen-generated table types.
template
class iterator ///
SOAGEN_HIDDEN_BASE(protected detail::iterator_storage>)
@@ -120,10 +120,10 @@ namespace soagen
/// @brief Alias for #row_type.
using reference = row_type;
- /// @brief This iterator type is a LegacyRandomAccessIterator.
+ /// @brief This iterator type is a RandomAccessIterator.
using iterator_category = std::random_access_iterator_tag;
-#if SOAGEN_CPP == 17
+#if SOAGEN_CPP <= 17
using pointer = void;
#endif
diff --git a/src/soagen/hpp/meta.hpp b/src/soagen/hpp/meta.hpp
index 02a2780..e411986 100644
--- a/src/soagen/hpp/meta.hpp
+++ b/src/soagen/hpp/meta.hpp
@@ -43,44 +43,47 @@ SOAGEN_ENABLE_WARNINGS;
static constexpr const char value[] = #Name; \
}; \
\
- template \
- struct named_ref_##Name \
+ template typename Transformation = soagen::identity_type> \
+ struct named_member_##Name \
{ \
- Ref Name; \
+ Transformation Name; \
\
protected: \
SOAGEN_PURE_INLINE_GETTER \
- constexpr Ref get_ref_impl() const noexcept \
+ constexpr decltype(auto) get_named_member() const noexcept \
{ \
- return static_cast[(Name); \
+ if constexpr (std::is_reference_v>) \
+ return static_cast>(Name); \
+ else \
+ return Name; \
} \
}
#endif
-#ifndef SOAGEN_MAKE_COL
- #define SOAGEN_MAKE_COL(Table, Column, Name) \
+#ifndef SOAGEN_MAKE_COLUMN
+ #define SOAGEN_MAKE_COLUMN(Table, Column, Name) \
template <> \
- struct col_name_] : name_constant_##Name \
+ struct column_name_ : name_constant_##Name \
{}; \
\
template <> \
struct col_ref_ \
- : named_ref_##Name>> \
+ : named_member_##Name>> \
{}; \
\
template <> \
struct col_ref_ \
- : named_ref_##Name>> \
+ : named_member_##Name>> \
{}; \
\
template <> \
struct col_ref_ \
- : named_ref_##Name>>> \
+ : named_member_##Name>>> \
{}; \
\
template <> \
struct col_ref_ \
- : named_ref_##Name>>> \
+ : named_member_##Name>>> \
{}
#endif
@@ -98,6 +101,10 @@ namespace soagen
template
using coerce_ref = std::conditional_t, T, std::add_lvalue_reference_t>;
+ /// @brief The identity type transformation.
+ template
+ using identity_type = T;
+
/// @brief True if `T` is `const` or `volatile` qualified.
template
inline constexpr bool is_cv = !std::is_same_v, T>;
@@ -589,7 +596,7 @@ namespace soagen
namespace detail
{
template
- struct col_name_;
+ struct column_name_;
template
struct col_ref_;
diff --git a/src/soagen/hpp/row.hpp b/src/soagen/hpp/row.hpp
index bac3498..a490710 100644
--- a/src/soagen/hpp/row.hpp
+++ b/src/soagen/hpp/row.hpp
@@ -25,7 +25,7 @@ namespace soagen
{
static_assert(Column < table_traits_type>::column_count, "column index out of range");
- return detail::col_ref_::get_ref_impl();
+ return detail::col_ref_::get_named_member();
}
// tuple protocol:
@@ -36,7 +36,7 @@ namespace soagen
{
static_assert(Member < sizeof...(Columns), "member index out of range");
- return type_at_index...>::get_ref_impl();
+ return type_at_index...>::get_named_member();
}
/// @name Equality
diff --git a/src/soagen/hpp/single/soagen.hpp b/src/soagen/hpp/single/soagen.hpp
index f684534..5c08271 100644
--- a/src/soagen/hpp/single/soagen.hpp
+++ b/src/soagen/hpp/single/soagen.hpp
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------------------------------------
//
-// soagen.hpp v0.1.1
+// soagen.hpp v0.1.2
// https://github.com/marzer/soagen
// SPDX-License-Identifier: MIT
//
@@ -9,17 +9,17 @@
//----------------------------------------------------------------------------------------------------------------------
//
// MIT License
-//
+//
// Copyright (c) Mark Gillard
-//
+//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to the following conditions:
-//
+//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
// Software.
-//
+//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
@@ -31,10 +31,10 @@
//******** generated/version.hpp *************************************************************************************
-#define SOAGEN_VERSION_MAJOR 0
-#define SOAGEN_VERSION_MINOR 1
-#define SOAGEN_VERSION_PATCH 1
-#define SOAGEN_VERSION_STRING "0.1.1"
+#define SOAGEN_VERSION_MAJOR 0
+#define SOAGEN_VERSION_MINOR 1
+#define SOAGEN_VERSION_PATCH 2
+#define SOAGEN_VERSION_STRING "0.1.2"
//******** generated/preprocessor.hpp ********************************************************************************
@@ -1204,44 +1204,47 @@ SOAGEN_DISABLE_SPAM_WARNINGS;
static constexpr const char value[] = #Name; \
}; \
\
- template \
- struct named_ref_##Name \
+ template typename Transformation = soagen::identity_type> \
+ struct named_member_##Name \
{ \
- Ref Name; \
+ Transformation Name; \
\
protected: \
SOAGEN_PURE_INLINE_GETTER \
- constexpr Ref get_ref_impl() const noexcept \
+ constexpr decltype(auto) get_named_member() const noexcept \
{ \
- return static_cast[(Name); \
+ if constexpr (std::is_reference_v>) \
+ return static_cast>(Name); \
+ else \
+ return Name; \
} \
}
#endif
-#ifndef SOAGEN_MAKE_COL
- #define SOAGEN_MAKE_COL(Table, Column, Name) \
+#ifndef SOAGEN_MAKE_COLUMN
+ #define SOAGEN_MAKE_COLUMN(Table, Column, Name) \
template <> \
- struct col_name_] : name_constant_##Name \
+ struct column_name_ : name_constant_##Name \
{}; \
\
template <> \
struct col_ref_ \
- : named_ref_##Name>> \
+ : named_member_##Name>> \
{}; \
\
template <> \
struct col_ref_ \
- : named_ref_##Name>> \
+ : named_member_##Name>> \
{}; \
\
template <> \
struct col_ref_ \
- : named_ref_##Name>>> \
+ : named_member_##Name>>> \
{}; \
\
template <> \
struct col_ref_ \
- : named_ref_##Name>>> \
+ : named_member_##Name>>> \
{}
#endif
@@ -1256,6 +1259,9 @@ namespace soagen
template
using coerce_ref = std::conditional_t, T, std::add_lvalue_reference_t>;
+ template
+ using identity_type = T;
+
template
inline constexpr bool is_cv = !std::is_same_v, T>;
@@ -1650,7 +1656,7 @@ namespace soagen
namespace detail
{
template
- struct col_name_;
+ struct column_name_;
template
struct col_ref_;
@@ -1727,7 +1733,7 @@ namespace soagen
{
static_assert(Column < table_traits_type>::column_count, "column index out of range");
- return detail::col_ref_::get_ref_impl();
+ return detail::col_ref_::get_named_member();
}
// tuple protocol:
@@ -1738,7 +1744,7 @@ namespace soagen
{
static_assert(Member < sizeof...(Columns), "member index out of range");
- return type_at_index...>::get_ref_impl();
+ return type_at_index...>::get_named_member();
}
SOAGEN_CONSTRAINED_TEMPLATE((detail::same_table_type
@@ -3455,8 +3461,8 @@ namespace soagen::detail
namespace soagen
{
template ,
- size_t Align = alignof(ValueType)>
+ size_t Align = alignof(ValueType),
+ typename ParamType = soagen::param_type>
struct SOAGEN_EMPTY_BASES column_traits //
SOAGEN_HIDDEN_BASE(public detail::column_traits_base>)
{
@@ -3468,6 +3474,11 @@ namespace soagen
static_assert(alignof(value_type) == alignof(typename base_traits::storage_type));
static_assert(sizeof(value_type) == sizeof(typename base_traits::storage_type));
+ static constexpr size_t alignment = max(Align, alignof(value_type));
+ static_assert(has_single_bit(alignment), "column alignment must be a power of two");
+
+ static constexpr size_t aligned_stride = lcm(alignment, sizeof(value_type)) / sizeof(value_type);
+
using param_type = ParamType;
static_assert(!std::is_void_v, "column param_type may not be void");
static_assert(std::is_reference_v || !is_cv,
@@ -3482,17 +3493,12 @@ namespace soagen
using rvalue_forward_type = forward_type;
using default_emplace_type = make_cref;
-
- static constexpr size_t alignment = max(Align, alignof(value_type));
- static_assert(has_single_bit(alignment), "column alignment must be a power of two");
-
- static constexpr size_t aligned_stride = lcm(alignment, sizeof(value_type)) / sizeof(value_type);
};
template
inline constexpr bool is_column_traits = POXY_IMPLEMENTATION_DETAIL(false);
- template
- inline constexpr bool is_column_traits> = true;
+ template
+ inline constexpr bool is_column_traits> = true;
template
inline constexpr bool is_column_traits> = true;
template
@@ -3508,23 +3514,16 @@ namespace soagen::detail
template
struct to_base_traits_;
- template
- struct to_base_traits_>
+ template
+ struct to_base_traits_>
{
using type = column_traits_base>;
- static_assert(std::is_base_of_v>);
+ static_assert(std::is_base_of_v>);
};
template
using to_base_traits = typename to_base_traits_::type;
-
- template ,
- size_t Align = alignof(ValueType)>
- using make_column = soagen::column_traits;
}
#if SOAGEN_ALWAYS_OPTIMIZE
@@ -6511,7 +6510,8 @@ namespace soagen
};
}
template
- class iterator SOAGEN_HIDDEN_BASE(protected detail::iterator_storage>)
+ class iterator
+ SOAGEN_HIDDEN_BASE(protected detail::iterator_storage>)
{
public:
using table_type = remove_cvref;
@@ -6533,11 +6533,12 @@ namespace soagen
using iterator_category = std::random_access_iterator_tag;
-#if SOAGEN_CPP == 17
+#if SOAGEN_CPP <= 17
using pointer = void;
#endif
private:
+
using base = detail::iterator_storage>;
using table_ptr = std::add_pointer_t>;
diff --git a/src/soagen/main.py b/src/soagen/main.py
index dc275f0..895c75b 100644
--- a/src/soagen/main.py
+++ b/src/soagen/main.py
@@ -178,7 +178,7 @@ def update(
),
recursive=recursive,
):
- if str(file).find('.egg-info') != -1 or file.name.lower.find('changelog') != -1:
+ if str(file).find('.egg-info') != -1 or file.name.lower().find('changelog') != -1:
continue
text = utils.read_all_text_from_file(file, logger=log.d)
new_text = matcher.sub(VERSION_STRING, text)
@@ -239,10 +239,6 @@ def update(
license = utils.read_all_text_from_file(paths.REPOSITORY / r'LICENSE.txt', log.i).replace('\r\n', '\n').strip()
license = '\n// '.join(utils.reflow_text(license, line_length=117).split('\n'))
text = utils.replace_metavar(r'license', license, text)
- try:
- text = utils.clang_format(text, cwd=soagen_hpp_in.parent)
- except:
- pass
log.i(rf'Writing {soagen_hpp_out}')
os.makedirs(str(paths.HPP_SINGLE), exist_ok=True)
with open(soagen_hpp_out, 'w', encoding='utf-8', newline='\n') as f:
@@ -430,16 +426,19 @@ def main_impl():
log.i(rf"Copying soagen.hpp to {args.install.resolve()}")
utils.copy_file(paths.HPP_SINGLE / r'soagen.hpp', args.install)
- configs = []
- for p in args.configs:
- if p.find('*') != -1:
- configs = configs + [f for f in Path('.').glob(p) if f.is_file()]
+ configs = set()
+ for config in args.configs:
+ if config == '.':
+ config = '*.toml'
+ if config.find('*') != -1:
+ configs.update([f for f in Path('.').glob(config) if f.is_file()])
else:
- p = Path(p)
- if not p.exists() or not p.is_file():
- log.e(rf"configs: '{p}' did not exist or was not a file")
- configs.append(p)
- configs.sort()
+ config = Path(config)
+ if config not in configs:
+ if not config.exists() or not config.is_file():
+ log.e(rf"configs: '{config}' did not exist or was not a file")
+ configs.add(config)
+ configs = sorted(configs)
if args.bug_report_internal:
os.makedirs(str(paths.BUG_REPORT_INPUTS), exist_ok=True)
for f in configs:
diff --git a/src/soagen/struct.py b/src/soagen/struct.py
index e462cbb..bdb9d05 100644
--- a/src/soagen/struct.py
+++ b/src/soagen/struct.py
@@ -191,13 +191,13 @@ def write_soagen_detail_specializations(self, o: Writer):
if i:
buf.write(f',\n')
col = self.columns[i]
- buf.write(f'{o.indent_str*4}/* {col.name:>{max_length}} */ make_column<{col.type}')
- if col.param_type:
- buf.write(rf', {col.param_type}')
+ buf.write(f'{o.indent_str*4}/* {col.name:>{max_length}} */ column_traits<{col.type}')
if col.alignment > 0:
+ buf.write(rf', soagen::max(size_t{{ {col.alignment} }}, alignof({col.type}))')
+ if col.param_type:
if not col.param_type:
- buf.write(rf', param_type<{col.type}>')
- buf.write(rf', {col.alignment}')
+ buf.write(rf', alignof({col.type})')
+ buf.write(rf', {col.param_type}')
buf.write(rf'>')
buf.write(rf'>')
o(
@@ -217,7 +217,7 @@ def write_soagen_detail_specializations(self, o: Writer):
)
for col in self.columns:
- o(rf'SOAGEN_MAKE_COL({self.qualified_name}, {col.index}, {col.name});')
+ o(rf'SOAGEN_MAKE_COLUMN({self.qualified_name}, {col.index}, {col.name});')
o(
rf'''
@@ -398,8 +398,8 @@ def doxygen(s: str) -> str:
o(
rf'''
- {doxygen(r"@brief Gets the name of the specified column as a string.")}
- template static constexpr auto& column_name = soagen::detail::col_name_<{self.name}, Column>::value;
+ {doxygen(r"@brief Gets the name of the specified column as a null-terminated string.")}
+ template static constexpr auto& column_name = soagen::detail::column_name_<{self.name}, Column>::value;
{self.header}
diff --git a/src/soagen/version.txt b/src/soagen/version.txt
index 17e51c3..d917d3e 100644
--- a/src/soagen/version.txt
+++ b/src/soagen/version.txt
@@ -1 +1 @@
-0.1.1
+0.1.2
diff --git a/src/soagen/writer.py b/src/soagen/writer.py
index 36faa95..840ef90 100644
--- a/src/soagen/writer.py
+++ b/src/soagen/writer.py
@@ -370,13 +370,15 @@ def __exit__(self, exc_type, exc_value, exc_traceback):
class ClangFormatOff(WriterBlockBase):
def __enter__(self):
- if self.writer.doxygen:
- self.writer('// clang-format off')
+ self.writer()
+ self.writer('// clang-format off')
+ self.writer()
return self
def __exit__(self, exc_type, exc_value, exc_traceback):
- if self.writer.doxygen:
- self.writer('// clang-format on')
+ self.writer()
+ self.writer('// clang-format on')
+ self.writer()
__all__ = [
diff --git a/tests/employees.hpp b/tests/employees.hpp
index 697c087..bcc8379 100644
--- a/tests/employees.hpp
+++ b/tests/employees.hpp
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------------------------------------------------
-// This file was generated by soagen v0.1.1 - do not modify it directly
+// This file was generated by soagen v0.1.2 - do not modify it directly
// https://marzer.github.io/soagen
//----------------------------------------------------------------------------------------------------------------------
#pragma once
@@ -36,6 +36,8 @@ SOAGEN_DISABLE_SPAM_WARNINGS;
// forward declarations + soagen internal boilerplate
//----------------------------------------------------------------------------------------------------------------------
+// clang-format off
+
namespace tests
{
class employees;
@@ -49,40 +51,40 @@ namespace soagen
namespace soagen::detail
{
-#ifndef SOAGEN_NAME_date_of_birth
- #define SOAGEN_NAME_date_of_birth
- SOAGEN_MAKE_NAME(date_of_birth);
-#endif
-
-#ifndef SOAGEN_NAME_id
- #define SOAGEN_NAME_id
- SOAGEN_MAKE_NAME(id);
-#endif
-
-#ifndef SOAGEN_NAME_name
- #define SOAGEN_NAME_name
- SOAGEN_MAKE_NAME(name);
-#endif
-
-#ifndef SOAGEN_NAME_salary
- #define SOAGEN_NAME_salary
- SOAGEN_MAKE_NAME(salary);
-#endif
-
-#ifndef SOAGEN_NAME_tag
- #define SOAGEN_NAME_tag
- SOAGEN_MAKE_NAME(tag);
-#endif
+ #ifndef SOAGEN_NAME_date_of_birth
+ #define SOAGEN_NAME_date_of_birth
+ SOAGEN_MAKE_NAME(date_of_birth);
+ #endif
+
+ #ifndef SOAGEN_NAME_id
+ #define SOAGEN_NAME_id
+ SOAGEN_MAKE_NAME(id);
+ #endif
+
+ #ifndef SOAGEN_NAME_name
+ #define SOAGEN_NAME_name
+ SOAGEN_MAKE_NAME(name);
+ #endif
+
+ #ifndef SOAGEN_NAME_salary
+ #define SOAGEN_NAME_salary
+ SOAGEN_MAKE_NAME(salary);
+ #endif
+
+ #ifndef SOAGEN_NAME_tag
+ #define SOAGEN_NAME_tag
+ SOAGEN_MAKE_NAME(tag);
+ #endif
template <>
struct table_traits_type_
{
using type = table_traits<
- /* name */ make_column,
- /* id */ make_column, 32>,
- /* date_of_birth */ make_column>,
- /* salary */ make_column,
- /* tag */ make_column>;
+ /* name */ column_traits,
+ /* id */ column_traits,
+ /* date_of_birth */ column_traits>,
+ /* salary */ column_traits,
+ /* tag */ column_traits>;
};
template <>
@@ -91,11 +93,11 @@ namespace soagen::detail
using type = soagen::allocator;
};
- SOAGEN_MAKE_COL(tests::employees, 0, name);
- SOAGEN_MAKE_COL(tests::employees, 1, id);
- SOAGEN_MAKE_COL(tests::employees, 2, date_of_birth);
- SOAGEN_MAKE_COL(tests::employees, 3, salary);
- SOAGEN_MAKE_COL(tests::employees, 4, tag);
+ SOAGEN_MAKE_COLUMN(tests::employees, 0, name);
+ SOAGEN_MAKE_COLUMN(tests::employees, 1, id);
+ SOAGEN_MAKE_COLUMN(tests::employees, 2, date_of_birth);
+ SOAGEN_MAKE_COLUMN(tests::employees, 3, salary);
+ SOAGEN_MAKE_COLUMN(tests::employees, 4, tag);
template <>
struct table_type_
@@ -104,6 +106,8 @@ namespace soagen::detail
};
}
+// clang-format on
+
//----------------------------------------------------------------------------------------------------------------------
// employees
//----------------------------------------------------------------------------------------------------------------------
@@ -161,7 +165,7 @@ namespace tests
};
template
- static constexpr auto& column_name = soagen::detail::col_name_::value;
+ static constexpr auto& column_name = soagen::detail::column_name_::value;
private:
table_type table_;
diff --git a/tests/employees.natvis b/tests/employees.natvis
index ca33431..c14d22d 100644
--- a/tests/employees.natvis
+++ b/tests/employees.natvis
@@ -1,6 +1,6 @@