|
/// @file stuffs.h |
|
/// @author Henrick Deschamps |
|
/// |
|
/// @brief Stuffs container class |
|
|
|
#ifndef GENERIC_CONTAINER_CLASS__STUFFS_H |
|
#define GENERIC_CONTAINER_CLASS__STUFFS_H |
|
|
|
#include <array> |
|
#include <deque> |
|
#include <iostream> |
|
#include <iterator> |
|
#include <forward_list> |
|
#include <list> |
|
#include <set> |
|
#include <unordered_set> |
|
#include <vector> |
|
|
|
#include "stuff.h" |
|
|
|
/// @class Stuff add functor |
|
/// @tparam Container the kind of container to add in |
|
template<class Container> |
|
struct [[maybe_unused]] StuffAdder final { |
|
/// @fn Call operator |
|
/// @param stuffs The stuffs container to add in |
|
/// @param stuff The stuff to add to the container |
|
auto operator()(Container &stuffs, Stuff &&stuff) const -> void; |
|
}; |
|
|
|
template<class Container> |
|
auto StuffAdder<Container>::operator()(Container &stuffs, Stuff &&stuff) const -> void { |
|
throw std::runtime_error("Unimplemented"); |
|
} |
|
|
|
/// @class Stuffs container |
|
/// @tparam Container The kind of stuff container |
|
/// @tparam StuffAdder The container stuff add functor, the default Container one by default |
|
template<class Container = std::vector<Stuff>, class StuffAdder = StuffAdder<Container>> |
|
class Stuffs final { |
|
private: |
|
/// @var The container |
|
Container container{}; |
|
|
|
/// @var The container stuff add functor |
|
StuffAdder stuff_adder_functor{}; |
|
|
|
/// @typedef The container iterator |
|
using ContainerIt = typename Container::iterator; |
|
|
|
/// @typedef The container const iterator |
|
using ContainerConstIt = typename Container::const_iterator; |
|
public: |
|
|
|
/// @fn Stuff default constructor |
|
Stuffs() = default; |
|
|
|
/// @fn Add stuff |
|
/// @brief Add a stuff to the stuff container |
|
/// @param stuff The stuff to add |
|
[[maybe_unused]] auto add_stuff(Stuff &&stuff) -> void { |
|
stuff_adder_functor(container, std::move(stuff)); |
|
} |
|
|
|
/// @fn Stuff container begin iterator generator |
|
/// @return Begin iterator |
|
[[maybe_unused]] [[nodiscard]] inline auto begin() -> ContainerIt { return container.begin(); } |
|
|
|
/// @fn Stuff container end iterator generator |
|
/// @return End iterator |
|
[[maybe_unused]] [[nodiscard]] inline auto end() -> ContainerIt { return container.end(); } |
|
|
|
/// @fn Stuff container begin const iterator generator |
|
/// @return Begin const iterator |
|
[[maybe_unused]] [[nodiscard]] inline auto begin() const -> ContainerConstIt { return container.begin(); } |
|
|
|
/// @fn Stuff container end const iterator generator |
|
/// @return End const iterator |
|
[[maybe_unused]] [[nodiscard]] inline auto end() const -> ContainerConstIt { return container.end(); } |
|
}; |
|
|
|
template<> |
|
struct [[maybe_unused]] StuffAdder<std::vector<Stuff>> final { |
|
auto operator()(std::vector<Stuff> &stuffs, |
|
Stuff &&stuff) const -> void { stuffs.push_back(std::move(stuff)); }; |
|
}; |
|
|
|
constexpr auto BUFFER_LEN = (10U); |
|
|
|
template<> |
|
struct [[maybe_unused]] StuffAdder<std::array<Stuff, BUFFER_LEN>> final { |
|
static unsigned int index; |
|
auto operator()(std::array<Stuff, BUFFER_LEN> &stuffs, Stuff &&stuff) const -> void { |
|
stuffs[index++ % BUFFER_LEN] = std::move(stuff); |
|
} |
|
}; |
|
|
|
unsigned int StuffAdder<std::array<Stuff, BUFFER_LEN>>::index = 0U; |
|
|
|
template<> |
|
struct [[maybe_unused]] StuffAdder<std::deque<Stuff>> final { |
|
auto operator()(std::deque<Stuff> &stuffs, Stuff &&stuff) const -> void { stuffs.push_back(std::move(stuff)); } |
|
}; |
|
|
|
template<> |
|
struct [[maybe_unused]] StuffAdder<std::list<Stuff>> final { |
|
auto operator()(std::list<Stuff> &stuffs, Stuff &&stuff) const -> void { stuffs.push_front(std::move(stuff)); } |
|
}; |
|
|
|
template<> |
|
struct [[maybe_unused]] StuffAdder<std::forward_list<Stuff>> final { |
|
auto operator()(std::forward_list<Stuff> &stuffs, |
|
Stuff &&stuff) const -> void { stuffs.push_front(std::move(stuff)); } |
|
}; |
|
|
|
template<> |
|
struct [[maybe_unused]] StuffAdder<std::set<Stuff>> final { |
|
auto operator()(std::set<Stuff> &stuffs, Stuff &&stuff) const -> void { stuffs.insert(std::move(stuff)); } |
|
}; |
|
|
|
template<> |
|
struct [[maybe_unused]] StuffAdder<std::multiset<Stuff>> final { |
|
auto operator()(std::multiset<Stuff> &stuffs, Stuff &&stuff) const -> void { stuffs.insert(std::move(stuff)); } |
|
}; |
|
|
|
template<> |
|
struct [[maybe_unused]] StuffAdder<std::unordered_set<Stuff>> final { |
|
auto operator()(std::unordered_set<Stuff> &stuffs, Stuff &&stuff) const -> void { stuffs.insert(std::move(stuff)); } |
|
}; |
|
|
|
template<> |
|
struct [[maybe_unused]] StuffAdder<std::unordered_multiset<Stuff>> final { |
|
auto operator()(std::unordered_multiset<Stuff> &stuffs, Stuff &&stuff) -> void { stuffs.insert(std::move(stuff)); } |
|
}; |
|
|
|
#endif //GENERIC_CONTAINER_CLASS__STUFFS_H |