summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/plib/putil.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/netlist/plib/putil.h')
-rw-r--r--src/lib/netlist/plib/putil.h87
1 files changed, 74 insertions, 13 deletions
diff --git a/src/lib/netlist/plib/putil.h b/src/lib/netlist/plib/putil.h
index 734442ff96a..ae383aaf807 100644
--- a/src/lib/netlist/plib/putil.h
+++ b/src/lib/netlist/plib/putil.h
@@ -17,15 +17,18 @@
#include <sstream>
#include <vector>
-#define PSTRINGIFY_HELP(y) # y
+#define PSTRINGIFY_HELP(y) #y
#define PSTRINGIFY(x) PSTRINGIFY_HELP(x)
-// Discussion and background of this MSVC bug: https://github.com/mamedev/mame/issues/6106
+// Discussion and background of this MSVC bug:
+// https://github.com/mamedev/mame/issues/6106
///
/// \brief Macro to work around a bug in MSVC treatment of __VA_ARGS__
///
#define PMSVC_VARARG_BUG(MACRO, ARGS) MACRO ARGS
+// clang-format off
+
/// \brief Determine number of arguments in __VA_ARGS__
///
/// This macro works up to 16 arguments in __VA_ARGS__
@@ -70,13 +73,16 @@
#define PSTRINGIFY_16(x, x2, x3, x4, x5, x6, x7, x8, x9, xa, xb, xc, xd, xe, xf, x10) \
#x, #x2, #x3, #x4, #x5, #x6, #x7, #x8, #x9, #xa, #xb, #xc, #xd, #xe, #xf, #x10
+// clang-format on
+
/// \brief Individually stringify up to 16 arguments
///
/// PSTRINGIFY_VA(a, b, c) will be expanded to "a", "b", "c"
///
/// \returns List of stringified individual arguments
///
-#define PSTRINGIFY_VA(...) PMSVC_VARARG_BUG(PCONCAT, (PSTRINGIFY_, PNARGS(__VA_ARGS__)))(__VA_ARGS__)
+#define PSTRINGIFY_VA(...) \
+ PMSVC_VARARG_BUG(PCONCAT, (PSTRINGIFY_, PNARGS(__VA_ARGS__)))(__VA_ARGS__)
/// \brief Dispatch VARARG macro to specialized macros
///
@@ -93,7 +99,8 @@
///
/// \returns result of specialized macro
///
-#define PCALLVARARG(MAC, ...) PMSVC_VARARG_BUG(PCONCAT, (MAC, PNARGS(__VA_ARGS__)))(__VA_ARGS__)
+#define PCALLVARARG(MAC, ...) \
+ PMSVC_VARARG_BUG(PCONCAT, (MAC, PNARGS(__VA_ARGS__)))(__VA_ARGS__)
// FIXME:: __FUNCTION__ may be not be supported by all compilers.
@@ -107,7 +114,7 @@ namespace plib
pstring basename(const pstring &filename, const pstring &suffix = "");
pstring path(const pstring &filename);
bool exists(const pstring &filename);
- pstring build_path(std::initializer_list<pstring> list );
+ pstring build_path(std::initializer_list<pstring> list);
pstring environment(const pstring &var, const pstring &default_val);
} // namespace util
@@ -121,7 +128,7 @@ namespace plib
static constexpr const std::size_t npos = static_cast<std::size_t>(-1);
template <class C>
- std::size_t indexof(C &con, const typename C::value_type &elem)
+ std::size_t index_of(C &con, const typename C::value_type &elem)
{
auto it = std::find(con.begin(), con.end(), elem);
if (it != con.end())
@@ -130,7 +137,8 @@ namespace plib
}
template <class C>
- void insert_at(C &con, const std::size_t index, const typename C::value_type &elem)
+ void insert_at(C &con, const std::size_t index,
+ const typename C::value_type &elem)
{
con.insert(con.begin() + narrow_cast<std::ptrdiff_t>(index), elem);
}
@@ -142,19 +150,72 @@ namespace plib
}
} // namespace container
- // ----------------------------------------------------------------------------------------
- // simple hash
- // ----------------------------------------------------------------------------------------
-
+ /// \brief Consistent hash implementation
+ ///
+ /// Hash implementations in c++ standard libraries may differ and deliver
+ /// different results. This hash can be used as a replacement hash in e.g.
+ /// std::map to deliver consistent results.
+ ///
+ /// \tparam V result type
+ /// \tparam T buffer element type
+ /// \param buf pointer to buffer for which hash should be calculated
+ /// \param size number of buffer elements
+ /// \return the hash of the buffer
+ ///
template <typename V, typename T>
constexpr V hash(const T *buf, std::size_t size) noexcept
{
V result = 5381; // NOLINT
- for (const T* p = buf; p != buf + size; p++)
- result = ((result << 5) + result ) ^ (result >> (32 - 5)) ^ narrow_cast<std::size_t>(*p); // NOLINT
+ for (const T *p = buf; p != buf + size; p++)
+ result = ((result << 5) + result) ^ (result >> (32 - 5))
+ ^ narrow_cast<std::size_t>(*p); // NOLINT
return result;
}
+ /// \brief Execute code at end of block
+ ///
+ /// The class can be used to execute code at the end of a block. It follows
+ /// the same design as std::lock_guard.
+ ///
+ /// Since the functor is executed in the destructor of the class the
+ /// execution is protected by a try catch block. If an exception is raised,
+ /// \ref plib::terminate is called.
+ ///
+ /// \tparam F type of functor - will be derived by template deduction guide
+ ///
+ template <typename F>
+ struct functor_guard
+ {
+ /// \brief constructor
+ ///
+ /// \param f functor to execute
+ functor_guard(F &&f)
+ : m_f(std::move(f))
+ {
+ }
+ /// \brief destructor
+ ///
+ ~functor_guard()
+ {
+ try
+ {
+ m_f();
+ }
+ catch (...)
+ {
+ plib::terminate("exception raised in lambda_guard");
+ }
+ }
+
+ private:
+ F m_f;
+ };
+
+ /// \brief template deduction guide
+ ///
+ template <class F>
+ functor_guard(F f) -> functor_guard<F>;
+
} // namespace plib
#endif // PUTIL_H_