summaryrefslogtreecommitdiff
path: root/tiger-compiler/lib/misc/xalloc.hh
diff options
context:
space:
mode:
Diffstat (limited to 'tiger-compiler/lib/misc/xalloc.hh')
-rw-r--r--tiger-compiler/lib/misc/xalloc.hh135
1 files changed, 135 insertions, 0 deletions
diff --git a/tiger-compiler/lib/misc/xalloc.hh b/tiger-compiler/lib/misc/xalloc.hh
new file mode 100644
index 0000000..1d819ef
--- /dev/null
+++ b/tiger-compiler/lib/misc/xalloc.hh
@@ -0,0 +1,135 @@
+/**
+ ** \file misc/xalloc.hh
+ ** \brief Declaration of misc::xalloc.
+ **/
+
+#pragma once
+
+#include <functional>
+#include <iostream>
+
+namespace misc
+{
+ /// Defines the operator() for the classes get_type, set_type and swap_type.
+ struct iomanipulator
+ {
+ virtual ~iomanipulator() = default;
+ virtual void operator()(std::ostream& o) const = 0;
+ };
+
+ /** \brief Launch the iomanipulator action on o.
+ **
+ ** Call the operator() of g (so set, get or swap the
+ ** xalloced data with data_).
+ */
+ std::ostream& operator<<(std::ostream& o, const iomanipulator& g);
+
+ /** \brief Allocate slots in std::ostreams.
+ **
+ ** Used to store flags in streams so that calling print
+ ** with additional parameters is no longer required (for
+ ** example in ast/libast.hh).
+ **
+ ** Set, get or swap data.
+ ** The idea is to build the right inner class with set, get or
+ ** swap methods, then use this class as a parameter of operator<<.
+ **
+ ** `StoredType` must be `CopyConstructible`. If it's not
+ ** `DefaultConstructible`, then arguments for its constructor are
+ ** to be passed to the `xalloc` constructor.
+ */
+ template <class StoredType> class xalloc
+ {
+ private:
+ /** \brief Handle the data to put in the xalloced place.
+ **
+ ** This inner class is used only with the set method.
+ */
+ class set_type : public iomanipulator
+ {
+ public:
+ /// Set data_ to data.
+ set_type(const xalloc& slot, StoredType& data);
+ /// Set the data in the xalloced place.
+ void operator()(std::ostream& ostr) const override;
+
+ private:
+ /// The xalloced data.
+ const xalloc& slot_;
+ /// Data to put in the stream.
+ StoredType& data_;
+ };
+
+ /** \brief Handle the data to get from the xalloced place.
+ **
+ ** This inner class is used only with the get method.
+ */
+ class get_type : public iomanipulator
+ {
+ public:
+ /// Set data_ to data.
+ get_type(const xalloc& slot, StoredType& data);
+
+ /// Get the data from the xalloced place.
+ void operator()(std::ostream& ostr) const override;
+
+ private:
+ /// The xalloced data.
+ const xalloc& slot_;
+ /// Variable in which we return the xalloc data.
+ StoredType& data_;
+ };
+
+ /** \brief Swap the data stored in the stream for a given one.
+ **
+ ** This inner class is used only with the swap method.
+ */
+ class swap_type : public iomanipulator
+ {
+ public:
+ /// Set data_ to data.
+ swap_type(const xalloc& slot, StoredType& data);
+
+ /// Swap the data from the xalloced place for a given one.
+ void operator()(std::ostream& ostr) const override;
+
+ private:
+ /// The xalloced data.
+ const xalloc& slot_;
+ /// Variable in which we store the data to be swapped.
+ StoredType& data_;
+ };
+
+ /// The index of the slot.
+ const long int index_;
+ // The model that is used to create new instances.
+ const StoredType model_;
+
+ public:
+ /// Allocates the slot.
+ template <typename... Args> xalloc(Args&&... args);
+
+ static void
+ deallocate(std::ios_base::event type, std::ios_base& ios, int index);
+
+ /// The xalloc index.
+ long int index() const;
+ /// The stored data as an lvalue.
+ StoredType& operator()(std::ostream& ostr) const;
+
+ /// A setter.
+ /// \param data where to find the value when the setter is executed.
+ set_type set(StoredType& data) const;
+
+ /// A getter.
+ /// \param data where to store the value when the getter is executed.
+ get_type get(StoredType& data) const;
+
+ /// A swapper.
+ /// \param data value to exchange when the swapper is executed.
+ swap_type swap(StoredType& data) const;
+ };
+
+} // namespace misc
+
+#include <misc/xalloc.hxx>