| // Copyright 2017-2020 The Verible 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 VERIBLE_COMMON_STRINGS_STRING_MEMORY_MAP_H_ | |
| #define VERIBLE_COMMON_STRINGS_STRING_MEMORY_MAP_H_ | |
| #include <utility> | |
| #include "absl/strings/string_view.h" | |
| #include "common/strings/range.h" | |
| #include "common/util/interval_map.h" | |
| #include "common/util/interval_set.h" | |
| #include "common/util/logging.h" | |
| namespace verible { | |
| namespace internal { | |
| inline std::pair<absl::string_view::const_iterator, | |
| absl::string_view::const_iterator> | |
| string_view_to_pair(absl::string_view sv) { | |
| return std::make_pair(sv.begin(), sv.end()); | |
| } | |
| } // namespace internal | |
| // StringViewSuperRangeMap maps a string_view to a super-range to which it | |
| // belongs. This can associate a string_view with the full text (file) from | |
| // which it originated. | |
| // Since this operates solely on string_views, it is not responsible for owning | |
| // any of the referenced memory -- the user is responsible for maintaining | |
| // proper string lifetime, owning strings must outlive these objects. | |
| class StringViewSuperRangeMap { | |
| typedef DisjointIntervalSet<absl::string_view::const_iterator> impl_type; | |
| public: | |
| // This iterator dereferences to a std::pair of | |
| // absl::string_view::const_iterator, which can be constructed into a | |
| // string_view. | |
| typedef impl_type::const_iterator const_iterator; | |
| StringViewSuperRangeMap() = default; | |
| StringViewSuperRangeMap(const StringViewSuperRangeMap&) = default; | |
| StringViewSuperRangeMap(StringViewSuperRangeMap&&) = default; | |
| StringViewSuperRangeMap& operator=(const StringViewSuperRangeMap&) = default; | |
| StringViewSuperRangeMap& operator=(StringViewSuperRangeMap&&) = default; | |
| bool empty() const { return string_map_.empty(); } | |
| const_iterator begin() const { return string_map_.begin(); } | |
| const_iterator end() const { return string_map_.end(); } | |
| // Given a substring, return an iterator pointing to the superstring that | |
| // fully contains the substring, if it exists, else return end(). | |
| const_iterator find(absl::string_view substring) const { | |
| return string_map_.find({substring.begin(), substring.end()}); | |
| } | |
| // Similar to find(), but asserts that a superstring range is found, | |
| // and converts the result directly to a string_view. | |
| absl::string_view must_find(absl::string_view substring) const { | |
| const const_iterator found(find(substring)); | |
| CHECK(found != string_map_.end()); | |
| return make_string_view_range(found->first, found->second); // superstring | |
| } | |
| // Insert a superstring (range) that does not overlap with any previously | |
| // inserted string range. This is suitable for string ranges that correspond | |
| // to allocated memory, because allocators only return non-overlapping memory | |
| // blocks. | |
| const_iterator must_emplace(absl::string_view superstring) { | |
| return string_map_.must_emplace(superstring.begin(), superstring.end()); | |
| } | |
| private: | |
| // Internal representation of string range map. | |
| impl_type string_map_; | |
| }; | |
| // StringMemoryMap maps (non-owned) string_views to owned memory. | |
| // This class provides a set-like interface to objects of type T. | |
| // T is any type of object that *owns* some string memory, whose | |
| // address range serves as a key. Since string addresses are the result of | |
| // allocation, they are guaranteed to not overlap. | |
| // T needs to be move-able, like a std::unique_ptr. | |
| // Note: std::string is move-able, but *not* guaranteed to maintain the same | |
| // address after std::move-ing. | |
| // RangeOf is any functor that returns a string_view of memory owned by objects | |
| // of type T. | |
| // | |
| // It is expected that the owned string memory address range never changes over | |
| // the lifetime of objects stored in this map, in other words, RangeOf(obj) will | |
| // always return the same range for the same object. One way to ensure this is | |
| // to make the underlying storage a 'const std::string'. | |
| // | |
| template <class T, absl::string_view RangeOf(const T&)> | |
| class StringMemoryMap { | |
| typedef absl::string_view::const_iterator key_type; | |
| typedef DisjointIntervalMap<key_type, T> map_type; | |
| public: | |
| typedef typename map_type::iterator iterator; | |
| StringMemoryMap() = default; | |
| StringMemoryMap(const StringMemoryMap&) = delete; | |
| StringMemoryMap(StringMemoryMap&&) = delete; | |
| StringMemoryMap& operator=(const StringMemoryMap&) = delete; | |
| StringMemoryMap& operator=(StringMemoryMap&&) = delete; | |
| // Returns reference to the object in the set that owns the memory range of | |
| // string 's', or else nullptr if 's' does not fall entirely within one of the | |
| // intervals in the map. | |
| const T* find(absl::string_view sv) const { | |
| const auto iter = memory_map_.find(internal::string_view_to_pair(sv)); | |
| if (iter == memory_map_.end()) return nullptr; | |
| return &iter->second; | |
| } | |
| // Move-inserts an element into the set, keyed on the memory range owned | |
| // by the object. | |
| iterator insert(T&& t) { | |
| const absl::string_view key = RangeOf(t); | |
| return memory_map_.must_emplace(internal::string_view_to_pair(key), | |
| std::move(t)); | |
| } | |
| private: | |
| map_type memory_map_; | |
| }; | |
| } // namespace verible | |
| #endif // VERIBLE_COMMON_STRINGS_STRING_MEMORY_MAP_H_ |