// Copyright (c) 2024 PaddlePaddle Authors. All Rights Reserved. // // 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. #pragma once #include #include #include #include "paddle/ap/include/adt/adt.h" #include "paddle/ap/include/axpr/hash.h" #include "paddle/ap/include/axpr/interpreter_base.h" #include "paddle/ap/include/axpr/type.h" namespace ap::axpr { template struct OrderedDictImpl { public: OrderedDictImpl() {} bool operator==(const OrderedDictImpl& other) const { return this == &other; } using ItemT = std::pair; const std::list& items() const { return items_; } adt::Result Has(InterpreterBase* interpreter, const KeyT& key) const { Hasher hasher{}; ADT_LET_CONST_REF(hash_value, hasher(interpreter, key)); const auto& iter_to_iters = this->hash_value2pair_iters_.find(hash_value); if (iter_to_iters == this->hash_value2pair_iters_.end()) { return false; } for (auto iter : iter_to_iters->second) { if (iter->first == key) { return true; } } return false; } adt::Result At(InterpreterBase* interpreter, const KeyT& key) const { Hasher hasher{}; ADT_LET_CONST_REF(hash_value, hasher(interpreter, key)); const auto& iter_to_iters = this->hash_value2pair_iters_.find(hash_value); ADT_CHECK(iter_to_iters != this->hash_value2pair_iters_.end()); for (auto iter : iter_to_iters->second) { if (iter->first == key) { return iter->second; } } return adt::errors::KeyError{"OrderedDictImpl::At() failed."}; } adt::Result Insert(InterpreterBase* interpreter, const ItemT& pair) { return Insert(interpreter, pair.first, pair.second); } adt::Result Insert(InterpreterBase* interpreter, const ValueT& key, const ValueT& val) { Hasher hasher{}; ADT_LET_CONST_REF(hash_value, hasher(interpreter, key)); auto* lst = &this->hash_value2pair_iters_[hash_value]; for (auto iter : *lst) { if (iter->first == key) { iter->second = val; return adt::Ok{}; } } lst->emplace_back( this->items_.insert(this->items_.end(), std::pair{key, val})); return adt::Ok{}; } private: using ItemsT = std::list; ItemsT items_; std::unordered_map> hash_value2pair_iters_; }; template ADT_DEFINE_RC(OrderedDict, OrderedDictImpl>); template struct TypeImpl> : public std::monostate { using std::monostate::monostate; const char* Name() const { return "OrderedDict"; } }; } // namespace ap::axpr