summaryrefslogtreecommitdiffstats
path: root/vespalib
diff options
context:
space:
mode:
authorTor Egge <Tor.Egge@online.no>2022-10-04 14:47:30 +0200
committerTor Egge <Tor.Egge@online.no>2022-10-04 14:47:30 +0200
commit1d6380f1350b8a9e5c00c9be2e2bd854bf88bcb3 (patch)
treed90c7534ceae3c11fd2ae6641cd6a59336eb2309 /vespalib
parent69069193606d6640829ff37d29a641a4e88244c3 (diff)
Add vespalib::datastore::Aligner.
Diffstat (limited to 'vespalib')
-rw-r--r--vespalib/src/vespa/vespalib/datastore/aligner.h45
1 files changed, 45 insertions, 0 deletions
diff --git a/vespalib/src/vespa/vespalib/datastore/aligner.h b/vespalib/src/vespa/vespalib/datastore/aligner.h
new file mode 100644
index 00000000000..c9879046dd6
--- /dev/null
+++ b/vespalib/src/vespa/vespalib/datastore/aligner.h
@@ -0,0 +1,45 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#pragma once
+
+#include <cstddef>
+#include <limits>
+
+namespace vespalib::datastore {
+
+inline constexpr size_t dynamic_alignment = std::numeric_limits<size_t>::max();
+
+/*
+ * Class used to align offsets to specified alignment.
+ *
+ * Alignment template parameter must be a power of 2 or the
+ * dynamic_alignment value (which triggers specialization below).
+ */
+template <size_t alignment_v = dynamic_alignment>
+class Aligner {
+public:
+ explicit constexpr Aligner() = default;
+ explicit constexpr Aligner(size_t); // Never used but must be declared
+ static size_t align(size_t unaligned) noexcept { return (unaligned + alignment_v - 1) & (- alignment_v); }
+ static size_t pad(size_t unaligned) noexcept { return (- unaligned & (alignment_v - 1)); }
+ static size_t alignment() noexcept { return alignment_v; }
+};
+
+/*
+ * Specialization when alignment template argument is dynamic_alignment.
+ * The constructor argument must be a power of 2.
+ */
+template <>
+class Aligner<dynamic_alignment> {
+ size_t _alignment;
+public:
+ explicit constexpr Aligner(size_t alignment_)
+ : _alignment(alignment_)
+ {
+ }
+ size_t align(size_t unaligned) const noexcept { return (unaligned + _alignment - 1) & (- _alignment); }
+ size_t pad(size_t unaligned) const noexcept { return (- unaligned & (_alignment - 1)); }
+ size_t alignment() const noexcept { return _alignment; }
+};
+
+}