-
Boost container
Hi there,
Before creating the subject, I was able to do research from the official documentation, forums but unfortunately, I could not or very well had an answer.
Context :
This is the code:
Code:
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/key.hpp>
template<typename Tkey, typename Tval>
class CacheWeb{
private:
using value_type = std::pair<Tkey, Tval>;
unsigned int capacity;
boost::multi_index_container<
value_type,
boost::multi_index::indexed_by<
boost::multi_index::sequenced<>,
boost::multi_index::hashed_unique<boost::multi_index::key<&value_type::first>>
>
> container;
CacheWeb(const CacheWeb&) = delete;
CacheWeb& operator=(const CacheWeb&) = delete;
int capacityOut(){
if( capacity == 0 || container.size() < capacity ) {
return 0;
}
int cnt = 0;
while(container.size() > capacity) {
container.pop_back();
++cnt;
}
return cnt;
};
public:
CacheWeb(int icapacity) : capacity(icapacity){};
virtual ~CacheWeb() = default;
int size(){
return container.size();
};
bool empty(){
return container.empty();
};
void clear(){
container.clear();
};
bool contains(const Tkey& key){
const auto& lookup = container.template get<1>();
return lookup.find(key) != container.template get<1>().end();
};
void remove(const Tkey& key){
container.erase(key);
};
void put(const Tkey& key, const Tval& val){
auto& lookup = container.template get<1>();
auto it = lookup.find(key);
if( it != lookup.end() ) {
lookup.modify(it,[&](value_type& x){ x.second = val; });
}
else{
it=lookup.emplace(key, val).first;
}
container.relocate(container.begin(),container.template project<0>(it));
capacityOut();
};
std::list<std::pair<Tkey, Tval>>getItems(){
return {container.begin(), container.end()};
};
const Tval& get(const Tkey& key){
const auto& lookup = container.template get<1>();
const auto it = lookup.find(key);
if( it == lookup.end() ) {
throw std::invalid_argument("Key does not exist");
}
return it->second;
}
};
#include <iostream>
int main()
{
CacheWeb<int,int> c(10);
for(int i=0;i<11;++i)c.put(i,i);
for(const auto& x:c.getItems()){
std::cout<<"("<<x.first<<","<<x.second<<")";
}
std::cout<<"\n";
for(int i=1;i<11;++i){
std::cout<<i<<"->"<<c.get(i)<<" ";
}
std::cout<<"\n";
}
Unfortunately, several questions come to my mind and also some problems:
1- At this line:
Code:
boost::multi_index_container<value_type,boost::multi_index::indexed_by<boost::multi_index::sequenced<>,boost::multi_index::hashed_unique<boost::multi_index::key<&value_type::first>>>> container;
I don't really well understand the concept behind this? It is a "container" variable of generic type "boost::multi_index_container" where each element is of type "value_type" and with 2 indexes ?
2 – Compared to the previous line of code of the container, so this one:
Code:
boost::multi_index_container<value_type,boost::multi_index::indexed_by<boost::multi_index::sequenced<>,boost::multi_index::hashed_unique<boost::multi_index::key<&value_type::first>>>> container;
I builde the code to better understand what it was doing, but I get a few errors:
2.1: Too few template arguments for class template 'sequenced'clang(template_arg_list_different_arity )
2.2: No member named 'key' in namespace 'boost::multi_index'clang(no_member)
I tried to solve the problem by modifying the container
Code:
boost::multi_index::key<&value_type::first>
By this:
Code:
boost::multi_index::member<value_type,Tkey,&value_type::first>
Unfortunately, I get this error: error: template argument 2 is invalid
3 – Last question, I misunderstand some functions related to boost:
3.1 templateget<1>();
3.2 location
I fumbled in the boost documents, but either I missed the page or I don't know.
Well, thank you for reading my post! Of course, I want to move forward with this project and my knowledge, and I have arrived at the time when I am looking for help.
I wish you a good day or evening.