@@ -61,4 +61,72 @@ RamDomain pack(RecordTableT&& recordTab, const std::initializer_list<RamDomain>&
6161 return recordTab.pack (std::data (initlist), initlist.size ());
6262}
6363
64+ /* *
65+ * @brief Construct a value belonging to an enumerated algebraic data type.
66+ *
67+ * An ADT is enumerated when none of its branches has fields.
68+ *
69+ * An ADT branch ID is the branch's zero-based position in the lexicographical
70+ * ordering of the ADT's qualified branch names.
71+ */
72+ inline RamDomain packADTEnum (const RamDomain branch) {
73+ return branch;
74+ }
75+
76+ /* *
77+ * @brief Construct a value belonging to a non-enumerated algebraic data type.
78+ *
79+ * An ADT is non-enumerated when at least one of its branches has a field. This
80+ * function must also be used for an empty branch of such an ADT.
81+ *
82+ * The arguments must already be represented as RamDomain values, using the
83+ * same symbol and record tables as the program that will consume the ADT. This
84+ * helper hides the special record encodings used for empty, unary, and
85+ * multi-argument branches.
86+ *
87+ * @param branch Zero-based position in the lexicographical ordering of the
88+ * ADT's qualified branch names.
89+ * @param arguments Branch field values in declaration order, encoded as
90+ * RamDomain values.
91+ */
92+ inline RamDomain packADT (
93+ RecordTable& recordTab, const RamDomain branch, const RamDomain* arguments, const std::size_t arity) {
94+ const RamDomain branchValue = arity == 1 ? arguments[0 ] : recordTab.pack (arguments, arity);
95+ return recordTab.pack ({branch, branchValue});
96+ }
97+
98+ /* *
99+ * @brief Construct a non-enumerated ADT value from an initialization list.
100+ * @param branch Zero-based position in lexicographical branch-name order.
101+ * @param arguments Branch field values in declaration order, encoded as
102+ * RamDomain values.
103+ */
104+ inline RamDomain packADT (
105+ RecordTable& recordTab, const RamDomain branch, const std::initializer_list<RamDomain>& arguments) {
106+ return packADT (recordTab, branch, std::data (arguments), arguments.size ());
107+ }
108+
109+ /* *
110+ * @brief Construct a non-enumerated ADT value from a fixed-size tuple.
111+ * @param branch Zero-based position in lexicographical branch-name order.
112+ * @param arguments Branch field values in declaration order, encoded as
113+ * RamDomain values.
114+ */
115+ template <std::size_t Arity>
116+ RamDomain packADT (RecordTable& recordTab, const RamDomain branch, const Tuple<RamDomain, Arity>& arguments) {
117+ return packADT (recordTab, branch, arguments.data (), Arity);
118+ }
119+
120+ /* *
121+ * @brief Construct a non-enumerated ADT value from a span.
122+ * @param branch Zero-based position in lexicographical branch-name order.
123+ * @param arguments Branch field values in declaration order, encoded as
124+ * RamDomain values.
125+ */
126+ template <std::size_t Arity>
127+ RamDomain packADT (
128+ RecordTable& recordTab, const RamDomain branch, const span<const RamDomain, Arity> arguments) {
129+ return packADT (recordTab, branch, arguments.data (), arguments.size ());
130+ }
131+
64132} // namespace souffle
0 commit comments