mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-21 02:39:11 +00:00
Move type_manager to type/ folder
This CL moves the type_manager from sem to type and updates the namespace as needed. Bug: tint:1718 Change-Id: I1fe0c2be08146221e68a9d2e7450283d102afdfa Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/113280 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Ben Clayton <bclayton@google.com> Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
committed by
Dawn LUCI CQ
parent
3e14a76425
commit
c9949ac59e
24
src/tint/type/type_manager.cc
Normal file
24
src/tint/type/type_manager.cc
Normal file
@@ -0,0 +1,24 @@
|
||||
// Copyright 2022 The Tint Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/tint/type/type_manager.h"
|
||||
|
||||
namespace tint::type {
|
||||
|
||||
TypeManager::TypeManager() = default;
|
||||
TypeManager::TypeManager(TypeManager&&) = default;
|
||||
TypeManager& TypeManager::operator=(TypeManager&& rhs) = default;
|
||||
TypeManager::~TypeManager() = default;
|
||||
|
||||
} // namespace tint::type
|
||||
152
src/tint/type/type_manager.h
Normal file
152
src/tint/type/type_manager.h
Normal file
@@ -0,0 +1,152 @@
|
||||
// Copyright 2022 The Tint Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SRC_TINT_TYPE_TYPE_MANAGER_H_
|
||||
#define SRC_TINT_TYPE_TYPE_MANAGER_H_
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
|
||||
#include "src/tint/sem/struct.h"
|
||||
#include "src/tint/type/array_count.h"
|
||||
#include "src/tint/type/node.h"
|
||||
#include "src/tint/type/type.h"
|
||||
#include "src/tint/utils/unique_allocator.h"
|
||||
|
||||
namespace tint::type {
|
||||
|
||||
/// The type manager holds all the pointers to the known types.
|
||||
class TypeManager final {
|
||||
public:
|
||||
/// Iterator is the type returned by begin() and end()
|
||||
using TypeIterator = utils::BlockAllocator<type::Type>::ConstIterator;
|
||||
|
||||
/// Constructor
|
||||
TypeManager();
|
||||
|
||||
/// Move constructor
|
||||
TypeManager(TypeManager&&);
|
||||
|
||||
/// Move assignment operator
|
||||
/// @param rhs the Manager to move
|
||||
/// @return this Manager
|
||||
TypeManager& operator=(TypeManager&& rhs);
|
||||
|
||||
/// Destructor
|
||||
~TypeManager();
|
||||
|
||||
/// Wrap returns a new Manager created with the types of `inner`.
|
||||
/// The Manager returned by Wrap is intended to temporarily extend the types
|
||||
/// of an existing immutable Manager.
|
||||
/// As the copied types are owned by `inner`, `inner` must not be destructed
|
||||
/// or assigned while using the returned Manager.
|
||||
/// TODO(bclayton) - Evaluate whether there are safer alternatives to this
|
||||
/// function. See crbug.com/tint/460.
|
||||
/// @param inner the immutable Manager to extend
|
||||
/// @return the Manager that wraps `inner`
|
||||
static TypeManager Wrap(const TypeManager& inner) {
|
||||
TypeManager out;
|
||||
out.types_.Wrap(inner.types_);
|
||||
out.nodes_.Wrap(inner.nodes_);
|
||||
return out;
|
||||
}
|
||||
|
||||
/// @param args the arguments used to construct the object.
|
||||
/// @return a pointer to an instance of `T` with the provided arguments.
|
||||
/// If an existing instance of `T` has been constructed, then the same
|
||||
/// pointer is returned.
|
||||
template <typename TYPE,
|
||||
typename _ = std::enable_if<traits::IsTypeOrDerived<TYPE, type::Type>>,
|
||||
typename... ARGS>
|
||||
TYPE* Get(ARGS&&... args) {
|
||||
return types_.Get<TYPE>(std::forward<ARGS>(args)...);
|
||||
}
|
||||
|
||||
/// @param args the arguments used to create the temporary used for the search.
|
||||
/// @return a pointer to an instance of `T` with the provided arguments, or nullptr if the item
|
||||
/// was not found.
|
||||
template <typename TYPE,
|
||||
typename _ = std::enable_if<traits::IsTypeOrDerived<TYPE, type::Type>>,
|
||||
typename... ARGS>
|
||||
TYPE* Find(ARGS&&... args) const {
|
||||
return types_.Find<TYPE>(std::forward<ARGS>(args)...);
|
||||
}
|
||||
|
||||
/// @param args the arguments used to construct the object.
|
||||
/// @return a pointer to an instance of `T` with the provided arguments.
|
||||
/// If an existing instance of `T` has been constructed, then the same
|
||||
/// pointer is returned.
|
||||
template <typename TYPE,
|
||||
typename _ = std::enable_if<traits::IsTypeOrDerived<TYPE, type::ArrayCount> ||
|
||||
traits::IsTypeOrDerived<TYPE, sem::StructMemberBase>>,
|
||||
typename... ARGS>
|
||||
TYPE* GetNode(ARGS&&... args) {
|
||||
return nodes_.Get<TYPE>(std::forward<ARGS>(args)...);
|
||||
}
|
||||
|
||||
/// @returns an iterator to the beginning of the types
|
||||
TypeIterator begin() const { return types_.begin(); }
|
||||
/// @returns an iterator to the end of the types
|
||||
TypeIterator end() const { return types_.end(); }
|
||||
|
||||
private:
|
||||
utils::UniqueAllocator<type::Type> types_;
|
||||
utils::UniqueAllocator<type::Node> nodes_;
|
||||
};
|
||||
|
||||
} // namespace tint::type
|
||||
|
||||
namespace std {
|
||||
|
||||
/// std::hash specialization for tint::type::Node
|
||||
template <>
|
||||
struct hash<tint::type::Node> {
|
||||
/// @param type the type to obtain a hash from
|
||||
/// @returns the hash of the type
|
||||
size_t operator()(const tint::type::Node& type) const {
|
||||
if (const auto* ac = type.As<tint::type::ArrayCount>()) {
|
||||
return ac->Hash();
|
||||
} else if (type.Is<tint::sem::StructMemberBase>()) {
|
||||
return tint::TypeInfo::Of<tint::sem::StructMemberBase>().full_hashcode;
|
||||
}
|
||||
TINT_ASSERT(Type, false && "Unreachable");
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
/// std::equal_to specialization for tint::type::Node
|
||||
template <>
|
||||
struct equal_to<tint::type::Node> {
|
||||
/// @param a the first type to compare
|
||||
/// @param b the second type to compare
|
||||
/// @returns true if the two types are equal
|
||||
bool operator()(const tint::type::Node& a, const tint::type::Node& b) const {
|
||||
if (const auto* ac = a.As<tint::type::ArrayCount>()) {
|
||||
if (const auto* bc = b.As<tint::type::ArrayCount>()) {
|
||||
return ac->Equals(*bc);
|
||||
}
|
||||
return false;
|
||||
} else if (a.Is<tint::sem::StructMemberBase>()) {
|
||||
return &a == &b;
|
||||
}
|
||||
TINT_ASSERT(Type, false && "Unreachable");
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif // SRC_TINT_TYPE_TYPE_MANAGER_H_
|
||||
89
src/tint/type/type_manager_test.cc
Normal file
89
src/tint/type/type_manager_test.cc
Normal file
@@ -0,0 +1,89 @@
|
||||
// Copyright 2022 The Tint Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/tint/type/type_manager.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "src/tint/sem/i32.h"
|
||||
#include "src/tint/sem/u32.h"
|
||||
|
||||
namespace tint::type {
|
||||
namespace {
|
||||
|
||||
template <typename T>
|
||||
size_t count(const T& range_loopable) {
|
||||
size_t n = 0;
|
||||
for (auto it : range_loopable) {
|
||||
(void)it;
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
using TypeManagerTest = testing::Test;
|
||||
|
||||
TEST_F(TypeManagerTest, GetUnregistered) {
|
||||
TypeManager tm;
|
||||
auto* t = tm.Get<sem::I32>();
|
||||
ASSERT_NE(t, nullptr);
|
||||
EXPECT_TRUE(t->Is<sem::I32>());
|
||||
}
|
||||
|
||||
TEST_F(TypeManagerTest, GetSameTypeReturnsSamePtr) {
|
||||
TypeManager tm;
|
||||
auto* t = tm.Get<sem::I32>();
|
||||
ASSERT_NE(t, nullptr);
|
||||
EXPECT_TRUE(t->Is<sem::I32>());
|
||||
|
||||
auto* t2 = tm.Get<sem::I32>();
|
||||
EXPECT_EQ(t, t2);
|
||||
}
|
||||
|
||||
TEST_F(TypeManagerTest, GetDifferentTypeReturnsDifferentPtr) {
|
||||
TypeManager tm;
|
||||
type::Type* t = tm.Get<sem::I32>();
|
||||
ASSERT_NE(t, nullptr);
|
||||
EXPECT_TRUE(t->Is<sem::I32>());
|
||||
|
||||
type::Type* t2 = tm.Get<sem::U32>();
|
||||
ASSERT_NE(t2, nullptr);
|
||||
EXPECT_NE(t, t2);
|
||||
EXPECT_TRUE(t2->Is<sem::U32>());
|
||||
}
|
||||
|
||||
TEST_F(TypeManagerTest, Find) {
|
||||
TypeManager tm;
|
||||
auto* created = tm.Get<sem::I32>();
|
||||
|
||||
EXPECT_EQ(tm.Find<sem::U32>(), nullptr);
|
||||
EXPECT_EQ(tm.Find<sem::I32>(), created);
|
||||
}
|
||||
|
||||
TEST_F(TypeManagerTest, WrapDoesntAffectInner) {
|
||||
TypeManager inner;
|
||||
TypeManager outer = TypeManager::Wrap(inner);
|
||||
|
||||
inner.Get<sem::I32>();
|
||||
|
||||
EXPECT_EQ(count(inner), 1u);
|
||||
EXPECT_EQ(count(outer), 0u);
|
||||
|
||||
outer.Get<sem::U32>();
|
||||
|
||||
EXPECT_EQ(count(inner), 1u);
|
||||
EXPECT_EQ(count(outer), 1u);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace tint::type
|
||||
Reference in New Issue
Block a user