blob: 7a50640d7da4fa179d600dfbd3d0543d0896d0d4 [file] [log] [blame]
dan sinclair08903802022-12-14 18:13:37 +00001// Copyright 2022 The Tint Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#ifndef SRC_TINT_CONSTANT_COMPOSITE_H_
16#define SRC_TINT_CONSTANT_COMPOSITE_H_
17
dan sinclairb53b8cf2022-12-15 16:25:31 +000018#include "src/tint/constant/value.h"
dan sinclair08903802022-12-14 18:13:37 +000019#include "src/tint/number.h"
20#include "src/tint/type/type.h"
dan sinclair12fa3032023-04-19 23:52:33 +000021#include "src/tint/utils/castable.h"
dan sinclair08903802022-12-14 18:13:37 +000022#include "src/tint/utils/hash.h"
23#include "src/tint/utils/vector.h"
24
dan sinclair8626c9e2022-12-14 19:22:19 +000025namespace tint::constant {
dan sinclair08903802022-12-14 18:13:37 +000026
dan sinclairb53b8cf2022-12-15 16:25:31 +000027/// Composite holds a number of mixed child values.
Ben Clayton574b4b12023-03-09 23:22:27 +000028/// Composite may be of a vector, matrix, array or structure type.
dan sinclair08903802022-12-14 18:13:37 +000029/// If each element is the same type and value, then a Splat would be a more efficient constant
dan sinclairb53b8cf2022-12-15 16:25:31 +000030/// implementation. Use CreateComposite() to create the appropriate type.
dan sinclair12fa3032023-04-19 23:52:33 +000031class Composite : public utils::Castable<Composite, Value> {
dan sinclair08903802022-12-14 18:13:37 +000032 public:
33 /// Constructor
34 /// @param t the compsite type
35 /// @param els the composite elements
36 /// @param all_0 true if all elements are 0
37 /// @param any_0 true if any element is 0
Ben Clayton574b4b12023-03-09 23:22:27 +000038 Composite(const type::Type* t, utils::VectorRef<const Value*> els, bool all_0, bool any_0);
dan sinclair08903802022-12-14 18:13:37 +000039 ~Composite() override;
40
Ben Clayton574b4b12023-03-09 23:22:27 +000041 /// @copydoc Value::Type()
dan sinclair08903802022-12-14 18:13:37 +000042 const type::Type* Type() const override { return type; }
43
Ben Clayton574b4b12023-03-09 23:22:27 +000044 /// @copydoc Value::Index()
45 const Value* Index(size_t i) const override {
dan sinclair08903802022-12-14 18:13:37 +000046 return i < elements.Length() ? elements[i] : nullptr;
47 }
48
Ben Clayton574b4b12023-03-09 23:22:27 +000049 /// @copydoc Value::NumElements()
50 size_t NumElements() const override { return elements.Length(); }
51
52 /// @copydoc Value::AllZero()
dan sinclair08903802022-12-14 18:13:37 +000053 bool AllZero() const override { return all_zero; }
Ben Clayton574b4b12023-03-09 23:22:27 +000054
55 /// @copydoc Value::AnyZero()
dan sinclair08903802022-12-14 18:13:37 +000056 bool AnyZero() const override { return any_zero; }
Ben Clayton574b4b12023-03-09 23:22:27 +000057
Ben Clayton574b4b12023-03-09 23:22:27 +000058 /// @copydoc Value::Hash()
dan sinclair08903802022-12-14 18:13:37 +000059 size_t Hash() const override { return hash; }
60
dan sinclair529c3fd2023-01-06 02:57:36 +000061 /// Clones the constant into the provided context
62 /// @param ctx the clone context
63 /// @returns the cloned node
64 Composite* Clone(CloneContext& ctx) const override;
65
dan sinclair08903802022-12-14 18:13:37 +000066 /// The composite type
67 type::Type const* const type;
68 /// The composite elements
Ben Clayton574b4b12023-03-09 23:22:27 +000069 const utils::Vector<const Value*, 4> elements;
dan sinclair08903802022-12-14 18:13:37 +000070 /// True if all elements are zero
71 const bool all_zero;
72 /// True if any element is zero
73 const bool any_zero;
74 /// The hash of the composite
75 const size_t hash;
76
dan sinclairb53b8cf2022-12-15 16:25:31 +000077 protected:
Ben Clayton574b4b12023-03-09 23:22:27 +000078 /// @copydoc Value::InternalValue()
dan sinclairb53b8cf2022-12-15 16:25:31 +000079 std::variant<std::monostate, AInt, AFloat> InternalValue() const override { return {}; }
80
dan sinclair08903802022-12-14 18:13:37 +000081 private:
82 size_t CalcHash() {
83 auto h = utils::Hash(type, all_zero, any_zero);
84 for (auto* el : elements) {
85 h = utils::HashCombine(h, el->Hash());
86 }
87 return h;
88 }
89};
90
dan sinclair8626c9e2022-12-14 19:22:19 +000091} // namespace tint::constant
dan sinclair08903802022-12-14 18:13:37 +000092
93#endif // SRC_TINT_CONSTANT_COMPOSITE_H_