summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/plib/parray.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/netlist/plib/parray.h')
-rw-r--r--src/lib/netlist/plib/parray.h126
1 files changed, 126 insertions, 0 deletions
diff --git a/src/lib/netlist/plib/parray.h b/src/lib/netlist/plib/parray.h
new file mode 100644
index 00000000000..1be37b908cd
--- /dev/null
+++ b/src/lib/netlist/plib/parray.h
@@ -0,0 +1,126 @@
+// license:GPL-2.0+
+// copyright-holders:Couriersud
+/*
+ * parray.h
+ *
+ */
+
+#ifndef PARRAY_H_
+#define PARRAY_H_
+
+#include "palloc.h"
+#include "pconfig.h"
+#include "pexception.h"
+
+#include <array>
+#include <memory>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+namespace plib {
+
+ template <typename FT, int SIZE>
+ struct sizeabs
+ {
+ static constexpr std::size_t ABS() { return (SIZE < 0) ? static_cast<std::size_t>(0 - SIZE) : static_cast<std::size_t>(SIZE); }
+ using container = typename std::array<FT, ABS()> ;
+ };
+
+ template <typename FT>
+ struct sizeabs<FT, 0>
+ {
+ static constexpr const std::size_t ABS = 0;
+ using container = typename std::vector<FT, aligned_allocator<FT, PALIGN_VECTOROPT>>;
+ };
+
+ /**
+ * \brief Array with preallocated or dynamic allocation
+ *
+ * Passing SIZE > 0 has the same functionality as a std::array.
+ * SIZE = 0 is pure dynamic allocation, the actual array size is passed to the
+ * constructor.
+ * SIZE < 0 reserves std::abs(SIZE) elements statically in place allocated. The
+ * actual size is passed in by the constructor.
+ * This array is purely intended for HPC application where depending on the
+ * architecture a preference dynamic/static has to be made.
+ *
+ * This struct is not intended to be a full replacement to std::array.
+ * It is a subset to enable switching between dynamic and static allocation.
+ * I consider > 10% performance difference to be a use case.
+ */
+
+ template <typename FT, int SIZE>
+ struct parray
+ {
+ public:
+ static constexpr std::size_t SIZEABS() { return sizeabs<FT, SIZE>::ABS(); }
+
+ using base_type = typename sizeabs<FT, SIZE>::container;
+ using size_type = typename base_type::size_type;
+ using reference = typename base_type::reference;
+ using const_reference = typename base_type::const_reference;
+ using value_type = typename base_type::value_type;
+
+ template <int X = SIZE >
+ parray(size_type size, typename std::enable_if<X==0, int>::type = 0)
+ : m_a(size), m_size(size)
+ {
+ }
+
+#if 1
+ /* allow construction in fixed size arrays */
+ template <int X = SIZE >
+ parray(typename std::enable_if<(X > 0), int>::type = 0)
+ : m_size(X)
+ {
+ }
+#endif
+ template <int X = SIZE >
+ parray(size_type size, typename std::enable_if<X!=0, int>::type = 0)
+ : m_size(size)
+ {
+ if (SIZE < 0 && size > SIZEABS())
+ throw plib::pexception("parray: size error " + plib::to_string(size) + ">" + plib::to_string(SIZEABS()));
+ else if (SIZE > 0 && size != SIZEABS())
+ throw plib::pexception("parray: size error");
+ }
+
+ inline size_type size() const noexcept { return SIZE <= 0 ? m_size : SIZEABS(); }
+
+ constexpr size_type max_size() const noexcept { return base_type::max_size(); }
+
+ bool empty() const noexcept { return size() == 0; }
+
+#if 0
+ reference operator[](size_type i) /*noexcept*/
+ {
+ if (i >= m_size) throw plib::pexception("limits error " + to_string(i) + ">=" + to_string(m_size));
+ return m_a[i];
+ }
+ const_reference operator[](size_type i) const /*noexcept*/
+ {
+ if (i >= m_size) throw plib::pexception("limits error " + to_string(i) + ">=" + to_string(m_size));
+ return m_a[i];
+ }
+#else
+ C14CONSTEXPR reference operator[](size_type i) noexcept
+ {
+ return assume_aligned_ptr<FT, PALIGN_VECTOROPT>(&m_a[0])[i];
+ }
+ constexpr const_reference operator[](size_type i) const noexcept
+ {
+ return assume_aligned_ptr<FT, PALIGN_VECTOROPT>(&m_a[0])[i];
+ }
+#endif
+ FT * data() noexcept { return assume_aligned_ptr<FT, PALIGN_VECTOROPT>(m_a.data()); }
+ const FT * data() const noexcept { return assume_aligned_ptr<FT, PALIGN_VECTOROPT>(m_a.data()); }
+
+ private:
+ PALIGNAS_VECTOROPT()
+ base_type m_a;
+ size_type m_size;
+ };
+} // namespace plib
+
+#endif /* PARRAY_H_ */