kicad/thirdparty/3dxware_sdk/inc/SpaceMouse/CCookieCollection.hpp

108 lines
3.5 KiB
C++

#ifndef CCookieCollection_HPP_INCLUDED
#define CCookieCollection_HPP_INCLUDED
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (c) 2018-2021 3Dconnexion.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file CCookieCollection.hpp
* @brief Cookie collection.
*/
#include <navlib/navlib_types.h>
// stdlib
#include <map>
#include <memory>
#include <stdexcept>
#if (!defined(_MSC_VER) || (_MSC_VER > 1600))
#include <mutex>
#else
#pragma warning(disable : 4482) // non-standard
#include <boost/thread/lock_guard.hpp>
#include <boost/thread/mutex.hpp>
namespace std {
using boost::lock_guard;
using boost::mutex;
using boost::unique_lock;
} // namespace std
#endif
namespace TDx {
namespace SpaceMouse {
/// <summary>
/// The class maps a cookie to a weak_ptr<typeparam name="T"></typeparam>.
/// </summary>
template <class T> class CCookieCollection : protected std::map<navlib::param_t, std::weak_ptr<T>> {
typedef std::map<navlib::param_t, std::weak_ptr<T>> map_t;
public:
typedef typename map_t::size_type size_type;
/// <summary>
/// Gets the shared pointer to class T corresponding to the passed in cookie.
/// </summary>
/// <param name="cookie">The <see cref="navlib::param_t"/> to search for.</param>
/// <returns>The shared pointer to the instance of T</returns>
/// <exception cref="std::out_of_range">If the cookie does not exist.</exception>
std::shared_ptr<T> at(const navlib::param_t &cookie) {
std::lock_guard<std::mutex> guard(m_mutex);
typename map_t::iterator iter = map_t::find(cookie);
if (iter != map_t::end()) {
return iter->second.lock();
}
throw std::out_of_range("Cookie does not exist in the Collection");
}
/// <summary>
/// Removes the elements that match the cookie.
/// </summary>
/// <param name="cookie">The cookie entry to remove.</param>
/// <returns>The number of elements that have been removed.</returns>
size_type erase(const navlib::param_t &cookie) {
std::lock_guard<std::mutex> guard(m_mutex);
return map_t::erase(cookie);
}
/// <summary>
/// Inserts a weak pointer (to class T) and returns a cookie that is needed to retrieve it later.
/// </summary>
/// <param name="sp">Shared pointer to class T.</param>
/// <returns>A cookie that is needed to find the shared pointer.</returns>
navlib::param_t insert(const std::shared_ptr<T> &sp) {
navlib::param_t param = 0;
if (sp) {
std::lock_guard<std::mutex> guard(m_mutex);
do {
using namespace std::chrono;
param =
duration_cast<microseconds>(high_resolution_clock::now().time_since_epoch()).count();
} while (map_t::find(param) != map_t::end());
(*this)[param] = sp;
}
return param;
}
protected:
/// <summary>
/// When changing the contents of the collection always use the mutex as a guard
/// </summary>
std::mutex m_mutex;
};
} // namespace SpaceMouse
} // namespace TDx
#endif // CCookieCollection_HPP_INCLUDED