swift
memotable.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (C) 2016 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #ifndef SWIFT_MISC_MEMOTABLE_H
7 #define SWIFT_MISC_MEMOTABLE_H
8 
9 #include "misc/dictionary.h"
10 #include "misc/sequence.h"
11 
12 namespace swift::misc
13 {
17  template <typename T>
18  class CMemoTable
19  {
20  public:
22  int getIndex(const T &value)
23  {
24  int &index = m_dict[value];
25  if (!index)
26  {
27  m_list.push_back(value);
28  index = m_list.size();
29  }
30  return index - 1;
31  }
32 
34  const CSequence<T> &getTable() const { return m_list; }
35 
36  private:
37  CSequence<T> m_list;
39  };
40 
44  template <typename... Ts>
45  struct CMemoHelper
46  {
48  class CMemoizer : private CMemoTable<Ts>...
49  {
50  public:
52  template <typename T>
53  decltype(auto) maybeMemoize(const T &member)
54  {
55  if constexpr ((std::is_same_v<T, Ts> || ...)) { return this->CMemoTable<T>::getIndex(member); }
56  else { return std::as_const(member); }
57  }
58 
60  template <typename T>
61  const CSequence<T> &getTable() const
62  {
63  return this->CMemoTable<T>::getTable();
64  }
65  };
66 
68  class CUnmemoizer : private CSequence<Ts>...
69  {
70  public:
72  template <typename T>
74  {
75  return *this;
76  }
77 
80  template <typename T>
81  auto maybeUnmemoize(T &member) const
82  {
83  if constexpr ((std::is_same_v<T, Ts> || ...))
84  {
85  struct Memo // clazy:exclude=rule-of-three
86  {
87  int index;
88  T &member;
89  const CSequence<T> &list;
90  int &get() { return index; }
91  ~Memo()
92  {
93  if (index >= 0) { member = list[index]; }
94  }
95  };
96  return Memo { -1, member, static_cast<const CSequence<T> &>(*this) };
97  }
98  else { return std::ref(member); }
99  }
100  };
101  };
102 } // namespace swift::misc
103 
104 #endif // SWIFT_MISC_MEMOTABLE_H
Memoizer for Ts. Other types are passed through.
Definition: memotable.h:49
decltype(auto) maybeMemoize(const T &member)
If T is in Ts, return the index of member in the memo table. Otherwise, return member.
Definition: memotable.h:53
const CSequence< T > & getTable() const
Return the values in the T table as a flat list.
Definition: memotable.h:61
Unmemoizer for Ts. Other types are passed through.
Definition: memotable.h:69
auto maybeUnmemoize(T &member) const
If T is in Ts, return proxy that will assign to member through the value at the given index in the fl...
Definition: memotable.h:81
CSequence< T > & getTable()
Return reference to the flat list T table.
Definition: memotable.h:73
A data memoization pattern useful for compressing JSON representations of containers.
Definition: memotable.h:19
const CSequence< T > & getTable() const
Return the values in the table as a flat list.
Definition: memotable.h:34
int getIndex(const T &value)
Return the index of a value, inserting it if it is not already in the table.
Definition: memotable.h:22
Generic sequential container with value semantics.
Definition: sequence.h:86
Free functions in swift::misc.
Helper class for memoizing members of a value object.
Definition: memotable.h:46