Tessil / ordered-map

C++ hash map and hash set which preserve the order of insertion
MIT License
512 stars 66 forks source link

Insertion by iterator throws a compile error if a const iterator is used #23

Closed Bo98 closed 5 years ago

Bo98 commented 5 years ago

This works:

tsl::ordered_map<int, int> map = { {0, 2}, {1, 3} };
tsl::ordered_map<int, int> map2 = { map.begin(), map.end() };

but these do not:

tsl::ordered_map<int, int> map = { {0, 2}, {1, 3} };
tsl::ordered_map<int, int> map2 = { map.cbegin(), map.cend() };
const tsl::ordered_map<int, int> map = { {0, 2}, {1, 3} };
tsl::ordered_map<int, int> map2 = { map.begin(), map.end() };

Tested under VS 2017 15.9.7. Here's the wall of text from the compiler in case you can't reproduce the issue:

  ordered_map.h(280): error C2668: 'tsl::detail_ordered_hash::ordered_hash<std::pair<Key,T>,tsl::ordered_map<Key,T,std::hash<int>,std::equal_to<Key>,std::allocator<std::pair<Key,T>>,std::deque<std::pair<Key,T>,Allocator>,uint_least32_t>::KeySelect,tsl::ordered_map<Key,T,std::hash<int>,std::equal_to<Key>,Allocator,std::deque<std::pair<Key,T>,Allocator>,uint_least32_t>::ValueSelect,Hash,KeyEqual,Allocator,ValueTypeContainer,IndexType>::insert': ambiguous call to overloaded function
          with
          [
              Key=int,
              T=int,
              Allocator=std::allocator<std::pair<int,int>>,
              Hash=std::hash<int>,
              KeyEqual=std::equal_to<int>,
              ValueTypeContainer=std::deque<std::pair<int,int>,std::allocator<std::pair<int,int>>>,
              IndexType=uint_least32_t
          ]
  ordered_hash.h(562): note: could be 'void tsl::detail_ordered_hash::ordered_hash<std::pair<Key,T>,tsl::ordered_map<Key,T,std::hash<int>,std::equal_to<Key>,std::allocator<std::pair<Key,T>>,std::deque<std::pair<Key,T>,Allocator>,uint_least32_t>::KeySelect,tsl::ordered_map<Key,T,std::hash<int>,std::equal_to<Key>,Allocator,std::deque<std::pair<Key,T>,Allocator>,uint_least32_t>::ValueSelect,Hash,KeyEqual,Allocator,ValueTypeContainer,IndexType>::insert<InputIt>(InputIt,InputIt)'
          with
          [
              Key=int,
              T=int,
              Allocator=std::allocator<std::pair<int,int>>,
              Hash=std::hash<int>,
              KeyEqual=std::equal_to<int>,
              ValueTypeContainer=std::deque<std::pair<int,int>,std::allocator<std::pair<int,int>>>,
              IndexType=uint_least32_t,
              InputIt=tsl::detail_ordered_hash::ordered_hash<std::pair<int,int>,tsl::ordered_map<int,int,std::hash<int>,std::equal_to<int>,std::allocator<std::pair<int,int>>,std::deque<std::pair<int,int>,std::allocator<std::pair<int,int>>>,uint_least32_t>::KeySelect,tsl::ordered_map<int,int,std::hash<int>,std::equal_to<int>,std::allocator<std::pair<int,int>>,std::deque<std::pair<int,int>,std::allocator<std::pair<int,int>>>,uint_least32_t>::ValueSelect,std::hash<int>,std::equal_to<int>,std::allocator<std::pair<int,int>>,std::deque<std::pair<int,int>,std::allocator<std::pair<int,int>>>,uint_least32_t>::ordered_iterator<true>
          ]
  c:\users\bo anderson\documents\repositories\bpvault\deps\ordered-map\include\tsl\ordered_hash.h(553): note: or       'tsl::detail_ordered_hash::ordered_hash<std::pair<Key,T>,tsl::ordered_map<Key,T,std::hash<int>,std::equal_to<Key>,std::allocator<std::pair<Key,T>>,std::deque<std::pair<Key,T>,Allocator>,uint_least32_t>::KeySelect,tsl::ordered_map<Key,T,std::hash<int>,std::equal_to<Key>,Allocator,std::deque<std::pair<Key,T>,Allocator>,uint_least32_t>::ValueSelect,Hash,KeyEqual,Allocator,ValueTypeContainer,IndexType>::ordered_iterator<false> tsl::detail_ordered_hash::ordered_hash<std::pair<Key,T>,tsl::ordered_map<Key,T,Hash,KeyEqual,Allocator,ValueTypeContainer,IndexType>::KeySelect,tsl::ordered_map<Key,T,Hash,KeyEqual,Allocator,ValueTypeContainer,IndexType>::ValueSelect,Hash,KeyEqual,Allocator,ValueTypeContainer,IndexType>::insert<InputIt&>(tsl::detail_ordered_hash::ordered_hash<std::pair<Key,T>,tsl::ordered_map<Key,T,Hash,KeyEqual,Allocator,ValueTypeContainer,IndexType>::KeySelect,tsl::ordered_map<Key,T,Hash,KeyEqual,Allocator,ValueTypeContainer,IndexType>::ValueSelect,Hash,KeyEqual,Allocator,ValueTypeContainer,IndexType>::ordered_iterator<true>,P)'
          with
          [
              Key=int,
              T=int,
              Allocator=std::allocator<std::pair<int,int>>,
              Hash=std::hash<int>,
              KeyEqual=std::equal_to<int>,
              ValueTypeContainer=std::deque<std::pair<int,int>,std::allocator<std::pair<int,int>>>,
              IndexType=uint_least32_t,
              InputIt=tsl::detail_ordered_hash::ordered_hash<std::pair<int,int>,tsl::ordered_map<int,int,std::hash<int>,std::equal_to<int>,std::allocator<std::pair<int,int>>,std::deque<std::pair<int,int>,std::allocator<std::pair<int,int>>>,uint_least32_t>::KeySelect,tsl::ordered_map<int,int,std::hash<int>,std::equal_to<int>,std::allocator<std::pair<int,int>>,std::deque<std::pair<int,int>,std::allocator<std::pair<int,int>>>,uint_least32_t>::ValueSelect,std::hash<int>,std::equal_to<int>,std::allocator<std::pair<int,int>>,std::deque<std::pair<int,int>,std::allocator<std::pair<int,int>>>,uint_least32_t>::ordered_iterator<true>,
              P=tsl::detail_ordered_hash::ordered_hash<std::pair<int,int>,tsl::ordered_map<int,int,std::hash<int>,std::equal_to<int>,std::allocator<std::pair<int,int>>,std::deque<std::pair<int,int>,std::allocator<std::pair<int,int>>>,uint_least32_t>::KeySelect,tsl::ordered_map<int,int,std::hash<int>,std::equal_to<int>,std::allocator<std::pair<int,int>>,std::deque<std::pair<int,int>,std::allocator<std::pair<int,int>>>,uint_least32_t>::ValueSelect,std::hash<int>,std::equal_to<int>,std::allocator<std::pair<int,int>>,std::deque<std::pair<int,int>,std::allocator<std::pair<int,int>>>,uint_least32_t>::ordered_iterator<true> &
          ]
  ordered_map.h(280): note: while trying to match the argument list '(InputIt, InputIt)'
          with
          [
              InputIt=tsl::detail_ordered_hash::ordered_hash<std::pair<int,int>,tsl::ordered_map<int,int,std::hash<int>,std::equal_to<int>,std::allocator<std::pair<int,int>>,std::deque<std::pair<int,int>,std::allocator<std::pair<int,int>>>,uint_least32_t>::KeySelect,tsl::ordered_map<int,int,std::hash<int>,std::equal_to<int>,std::allocator<std::pair<int,int>>,std::deque<std::pair<int,int>,std::allocator<std::pair<int,int>>>,uint_least32_t>::ValueSelect,std::hash<int>,std::equal_to<int>,std::allocator<std::pair<int,int>>,std::deque<std::pair<int,int>,std::allocator<std::pair<int,int>>>,uint_least32_t>::ordered_iterator<true>
          ]
  ordered_map.h(167): note: see reference to function template instantiation 'void tsl::ordered_map<int,int,std::hash<int>,std::equal_to<Key>,std::allocator<std::pair<Key,T>>,std::deque<std::pair<Key,T>,Allocator>,uint_least32_t>::insert<InputIt>(InputIt,InputIt)' being compiled
          with
          [
              Key=int,
              T=int,
              Allocator=std::allocator<std::pair<int,int>>,
              InputIt=tsl::detail_ordered_hash::ordered_hash<std::pair<int,int>,tsl::ordered_map<int,int,std::hash<int>,std::equal_to<int>,std::allocator<std::pair<int,int>>,std::deque<std::pair<int,int>,std::allocator<std::pair<int,int>>>,uint_least32_t>::KeySelect,tsl::ordered_map<int,int,std::hash<int>,std::equal_to<int>,std::allocator<std::pair<int,int>>,std::deque<std::pair<int,int>,std::allocator<std::pair<int,int>>>,uint_least32_t>::ValueSelect,std::hash<int>,std::equal_to<int>,std::allocator<std::pair<int,int>>,std::deque<std::pair<int,int>,std::allocator<std::pair<int,int>>>,uint_least32_t>::ordered_iterator<true>
          ]
  ordered_map.h(167): note: see reference to function template instantiation 'void tsl::ordered_map<int,int,std::hash<int>,std::equal_to<Key>,std::allocator<std::pair<Key,T>>,std::deque<std::pair<Key,T>,Allocator>,uint_least32_t>::insert<InputIt>(InputIt,InputIt)' being compiled
          with
          [
              Key=int,
              T=int,
              Allocator=std::allocator<std::pair<int,int>>,
              InputIt=tsl::detail_ordered_hash::ordered_hash<std::pair<int,int>,tsl::ordered_map<int,int,std::hash<int>,std::equal_to<int>,std::allocator<std::pair<int,int>>,std::deque<std::pair<int,int>,std::allocator<std::pair<int,int>>>,uint_least32_t>::KeySelect,tsl::ordered_map<int,int,std::hash<int>,std::equal_to<int>,std::allocator<std::pair<int,int>>,std::deque<std::pair<int,int>,std::allocator<std::pair<int,int>>>,uint_least32_t>::ValueSelect,std::hash<int>,std::equal_to<int>,std::allocator<std::pair<int,int>>,std::deque<std::pair<int,int>,std::allocator<std::pair<int,int>>>,uint_least32_t>::ordered_iterator<true>
          ]
  test.cpp(419): note: see reference to function template instantiation 'tsl::ordered_map<int,int,std::hash<int>,std::equal_to<Key>,std::allocator<std::pair<Key,T>>,std::deque<std::pair<Key,T>,Allocator>,uint_least32_t>::ordered_map<tsl::detail_ordered_hash::ordered_hash<std::pair<Key,T>,tsl::ordered_map<Key,T,std::hash<int>,std::equal_to<Key>,Allocator,std::deque<std::pair<Key,T>,Allocator>,uint_least32_t>::KeySelect,tsl::ordered_map<Key,T,std::hash<int>,std::equal_to<Key>,Allocator,std::deque<std::pair<Key,T>,Allocator>,uint_least32_t>::ValueSelect,Hash,KeyEqual,Allocator,ValueTypeContainer,IndexType>::ordered_iterator<true>>(InputIt,InputIt,unsigned __int64,const Hash &,const KeyEqual &,const Allocator &)' being compiled
          with
          [
              Key=int,
              T=int,
              Allocator=std::allocator<std::pair<int,int>>,
              Hash=std::hash<int>,
              KeyEqual=std::equal_to<int>,
              ValueTypeContainer=std::deque<std::pair<int,int>,std::allocator<std::pair<int,int>>>,
              IndexType=uint_least32_t,
              InputIt=tsl::detail_ordered_hash::ordered_hash<std::pair<int,int>,tsl::ordered_map<int,int,std::hash<int>,std::equal_to<int>,std::allocator<std::pair<int,int>>,std::deque<std::pair<int,int>,std::allocator<std::pair<int,int>>>,uint_least32_t>::KeySelect,tsl::ordered_map<int,int,std::hash<int>,std::equal_to<int>,std::allocator<std::pair<int,int>>,std::deque<std::pair<int,int>,std::allocator<std::pair<int,int>>>,uint_least32_t>::ValueSelect,std::hash<int>,std::equal_to<int>,std::allocator<std::pair<int,int>>,std::deque<std::pair<int,int>,std::allocator<std::pair<int,int>>>,uint_least32_t>::ordered_iterator<true>
          ]
  test.cpp(419): note: see reference to function template instantiation 'tsl::ordered_map<int,int,std::hash<int>,std::equal_to<Key>,std::allocator<std::pair<Key,T>>,std::deque<std::pair<Key,T>,Allocator>,uint_least32_t>::ordered_map<tsl::detail_ordered_hash::ordered_hash<std::pair<Key,T>,tsl::ordered_map<Key,T,std::hash<int>,std::equal_to<Key>,Allocator,std::deque<std::pair<Key,T>,Allocator>,uint_least32_t>::KeySelect,tsl::ordered_map<Key,T,std::hash<int>,std::equal_to<Key>,Allocator,std::deque<std::pair<Key,T>,Allocator>,uint_least32_t>::ValueSelect,Hash,KeyEqual,Allocator,ValueTypeContainer,IndexType>::ordered_iterator<true>>(InputIt,InputIt,unsigned __int64,const Hash &,const KeyEqual &,const Allocator &)' being compiled
          with
          [
              Key=int,
              T=int,
              Allocator=std::allocator<std::pair<int,int>>,
              Hash=std::hash<int>,
              KeyEqual=std::equal_to<int>,
              ValueTypeContainer=std::deque<std::pair<int,int>,std::allocator<std::pair<int,int>>>,
              IndexType=uint_least32_t,
              InputIt=tsl::detail_ordered_hash::ordered_hash<std::pair<int,int>,tsl::ordered_map<int,int,std::hash<int>,std::equal_to<int>,std::allocator<std::pair<int,int>>,std::deque<std::pair<int,int>,std::allocator<std::pair<int,int>>>,uint_least32_t>::KeySelect,tsl::ordered_map<int,int,std::hash<int>,std::equal_to<int>,std::allocator<std::pair<int,int>>,std::deque<std::pair<int,int>,std::allocator<std::pair<int,int>>>,uint_least32_t>::ValueSelect,std::hash<int>,std::equal_to<int>,std::allocator<std::pair<int,int>>,std::deque<std::pair<int,int>,std::allocator<std::pair<int,int>>>,uint_least32_t>::ordered_iterator<true>
          ]

Both std::map and std::unordered_map seem to work fine under this case.

Tessil commented 5 years ago

Hi,

Thank you very much for the report. The commit df6530c767dd865c5be159492113096e0fc3d7f6 should fix this. Warn me if you still encounter the problem.