76 lines
1.9 KiB
C++
76 lines
1.9 KiB
C++
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
|
|
// de Barcelona (UAB).
|
|
//
|
|
// This work is licensed under the terms of the MIT license.
|
|
// For a copy, see <https://opensource.org/licenses/MIT>.
|
|
|
|
#pragma once
|
|
|
|
#include "carla/AtomicSharedPtr.h"
|
|
#include "carla/NonCopyable.h"
|
|
|
|
#include <algorithm>
|
|
#include <mutex>
|
|
#include <vector>
|
|
|
|
namespace carla {
|
|
namespace client {
|
|
namespace detail {
|
|
|
|
/// Holds an atomic pointer to a list.
|
|
///
|
|
/// @warning Only Load method is atomic, modifications to the list are locked
|
|
/// with a mutex.
|
|
template <typename T>
|
|
class AtomicList : private NonCopyable {
|
|
using ListT = std::vector<T>;
|
|
public:
|
|
|
|
AtomicList() : _list(std::make_shared<ListT>()) {}
|
|
|
|
template <typename ValueT>
|
|
void Push(ValueT &&value) {
|
|
std::lock_guard<std::mutex> lock(_mutex);
|
|
auto new_list = std::make_shared<ListT>(*Load());
|
|
new_list->emplace_back(std::forward<ValueT>(value));
|
|
_list = new_list;
|
|
}
|
|
|
|
void DeleteByIndex(size_t index) {
|
|
std::lock_guard<std::mutex> lock(_mutex);
|
|
auto new_list = std::make_shared<ListT>(*Load());
|
|
auto begin = new_list->begin();
|
|
std::advance(begin, index);
|
|
new_list->erase(begin);
|
|
_list = new_list;
|
|
}
|
|
|
|
template <typename ValueT>
|
|
void DeleteByValue(const ValueT &value) {
|
|
std::lock_guard<std::mutex> lock(_mutex);
|
|
auto new_list = std::make_shared<ListT>(*Load());
|
|
new_list->erase(std::remove(new_list->begin(), new_list->end(), value), new_list->end());
|
|
_list = new_list;
|
|
}
|
|
|
|
void Clear() {
|
|
std::lock_guard<std::mutex> lock(_mutex);
|
|
_list = std::make_shared<ListT>();
|
|
}
|
|
|
|
/// Returns a pointer to the list.
|
|
std::shared_ptr<const ListT> Load() const {
|
|
return _list.load();
|
|
}
|
|
|
|
private:
|
|
|
|
std::mutex _mutex;
|
|
|
|
AtomicSharedPtr<const ListT> _list;
|
|
};
|
|
|
|
} // namespace detail
|
|
} // namespace client
|
|
} // namespace carla
|