.. _program_listing_file__tmp_ws_src_fastrtps_include_fastdds_rtps_common_LocatorSelector.hpp: Program Listing for File LocatorSelector.hpp ============================================ |exhale_lsh| :ref:`Return to documentation for file ` (``/tmp/ws/src/fastrtps/include/fastdds/rtps/common/LocatorSelector.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp // Copyright 2019 Proyectos y Sistemas de Mantenimiento SL (eProsima). // // 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 _FASTDDS_RTPS_COMMON_LOCATORSELECTOR_HPP_ #define _FASTDDS_RTPS_COMMON_LOCATORSELECTOR_HPP_ #include #include #include #include #include #include namespace eprosima { namespace fastrtps { namespace rtps { class LocatorSelector { public: LocatorSelector( const ResourceLimitedContainerConfig& entries_allocation) : entries_(entries_allocation) , selections_(entries_allocation) , last_state_(entries_allocation) { } void clear() { entries_.clear(); selections_.clear(); last_state_.clear(); } bool add_entry( LocatorSelectorEntry* entry) { return entries_.push_back(entry) != nullptr; } bool remove_entry( const GUID_t& guid) { return entries_.remove_if( [&guid](LocatorSelectorEntry* entry) { return entry->remote_guid == guid; }); } void reset( bool enable_all) { last_state_.clear(); for (LocatorSelectorEntry* entry : entries_) { last_state_.push_back(entry->enabled ? 1 : 0); entry->enable(enable_all); } } void enable( const GUID_t& guid) { for (LocatorSelectorEntry* entry : entries_) { if (entry->remote_guid == guid) { entry->enabled = true; break; } } } bool state_has_changed() const { if (entries_.size() != last_state_.size()) { return true; } for (size_t i = 0; i < entries_.size(); ++i) { if (last_state_.at(i) != (entries_.at(i)->enabled ? 1 : 0)) { return true; } } return false; } void selection_start() { selections_.clear(); for (LocatorSelectorEntry* entry : entries_) { entry->reset(); } } ResourceLimitedVector& transport_starts() { for (LocatorSelectorEntry* entry : entries_) { entry->transport_should_process = entry->enabled; } return entries_; } void select( size_t index) { if (index < entries_.size() && std::find(selections_.begin(), selections_.end(), index) == selections_.end()) { selections_.push_back(index); } } size_t selected_size() const { size_t result = 0; for (size_t index : selections_) { LocatorSelectorEntry* entry = entries_.at(index); result += entry->state.multicast.size(); result += entry->state.unicast.size(); } return result; } bool is_selected( const Locator_t locator) const { if (IPLocator::isMulticast(locator)) { for (size_t index : selections_) { LocatorSelectorEntry* entry = entries_.at(index); for (size_t loc_index : entry->state.multicast) { if (entry->multicast.at(loc_index) == locator) { return true; } } } } else { for (size_t index : selections_) { LocatorSelectorEntry* entry = entries_.at(index); for (size_t loc_index : entry->state.unicast) { if (entry->unicast.at(loc_index) == locator) { return true; } } } } return false; } template void for_each( UnaryPredicate action) const { for (size_t index : selections_) { LocatorSelectorEntry* entry = entries_.at(index); for (size_t loc_index : entry->state.multicast) { action(entry->multicast.at(loc_index)); } for (size_t loc_index : entry->state.unicast) { action(entry->unicast.at(loc_index)); } } } struct IteratorIndex { size_t selections_index; size_t state_index; bool state_multicast_done; Locator_t* locator; }; class iterator : public LocatorsIterator { // use of std::iterator to introduce the following aliases is deprecated using iterator_category = std::input_iterator_tag; using value_type = Locator_t; using difference_type = IteratorIndex; using pointer = Locator_t*; using reference = Locator_t&; const LocatorSelector& locator_selector_; IteratorIndex current_; void go_to_next_entry() { // While entries selected while (++current_.selections_index < locator_selector_.selections_.size()) { LocatorSelectorEntry* entry = locator_selector_.entries_.at(locator_selector_.selections_[current_.selections_index]); // No multicast locators in this entry if (entry->state.multicast.size() == 0) { // But there's unicast if (entry->state.unicast.size() > 0) { current_.locator = &entry->unicast[entry->state.unicast.at(0)]; return; } } else // process multicast { current_.state_multicast_done = false; current_.locator = &entry->multicast[entry->state.multicast.at(0)]; return; } } current_.locator = nullptr; } public: enum class Position { Begin, End }; explicit iterator( const LocatorSelector& locator_selector, Position index_pos) : locator_selector_(locator_selector) { current_ = {(std::numeric_limits::max)(), 0, true, nullptr}; if (index_pos == Position::Begin) { go_to_next_entry(); } } iterator( const iterator& other) : locator_selector_(other.locator_selector_) , current_(other.current_) { } iterator& operator ++() { // Shouldn't call ++ when index already at the end assert(current_.selections_index < locator_selector_.selections_.size()); LocatorSelectorEntry* entry = locator_selector_.entries_.at(locator_selector_.selections_[current_.selections_index]); // Index at unicast locators if (current_.state_multicast_done) { // No more unicast locators selected if (++current_.state_index >= entry->state.unicast.size()) { current_.state_index = 0; go_to_next_entry(); } else // current unicast locator { current_.locator = &entry->unicast[entry->state.unicast.at(current_.state_index)]; } } else // Index at multicast locators { // No more multicast locators selected if (++current_.state_index >= entry->state.multicast.size()) { // Reset index to process unicast current_.state_multicast_done = true; current_.state_index = 0; // No unicast locators if (current_.state_index >= entry->state.unicast.size()) { go_to_next_entry(); } else // current unicast locator { current_.locator = &entry->unicast[entry->state.unicast.at(current_.state_index)]; } } else // current multicast locator { current_.locator = &entry->multicast[entry->state.multicast.at(current_.state_index)]; } } return *this; } bool operator ==( const LocatorsIterator& other) const { return *this == static_cast(other); } bool operator !=( const LocatorsIterator& other) const { return !(*this == other); } bool operator ==( const iterator& other) const { return (current_.locator == other.current_.locator); } bool operator !=( const iterator& other) const { return !(*this == other); } pointer operator ->() const { return current_.locator; } reference operator *() const { return *current_.locator; } }; iterator begin() const { return iterator(*this, iterator::Position::Begin); } iterator end() const { return iterator(*this, iterator::Position::End); } private: ResourceLimitedVector entries_; ResourceLimitedVector selections_; ResourceLimitedVector last_state_; }; } /* namespace rtps */ } /* namespace fastrtps */ } /* namespace eprosima */ #endif /* _FASTDDS_RTPS_COMMON_LOCATORSELECTOR_H_ */