Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use a non-number type as a key for maps (for example std::bitset) #48

Open
Jaimies opened this issue May 1, 2021 · 0 comments
Open

Comments

@Jaimies
Copy link

Jaimies commented May 1, 2021

I'm certain that this is a feature unsupported by junction, but just in case, I'll provide some system details.

OS: Ubuntu 20.04.2 LTS
Build system: CMake (used through CLion IDE). Not sure which CMake version it uses under the hood though.

I'm trying to create something like a transposition table for a chess engine. So the following code compiles:

#include <junction/ConcurrentMap_Leapfrog.h>

struct Foo {};

int main() {
    typedef junction::ConcurrentMap_Leapfrog<unsigned long long, Foo*> ConcurrentMap;
    ConcurrentMap map;
    return 0;
}

However, in my case, I'm unable to use unsigned long long as the position hash, because it can't hold enough values. So I use std::bitset. But there is a problem, the following won't compile:

#include <bitset>
#include <junction/ConcurrentMap_Leapfrog.h>

struct Foo {};

int main() {
    typedef junction::ConcurrentMap_Leapfrog<std::bitset<100>, Foo*> ConcurrentMap;
    ConcurrentMap map;
    return 0;
}

The error is the following:

In file included from /path/to/project/main.cpp:2:
/path/to/project/junction/junction/ConcurrentMap_Leapfrog.h: In instantiation of ‘class junction::ConcurrentMap_Leapfrog<std::bitset<100>, Foo*>’:
/path/to/project/main.cpp:8:19:   required from here
/path/to/project/junction/junction/ConcurrentMap_Leapfrog.h:33:57: error: invalid use of incomplete type ‘struct turf::util::BestFit<std::bitset<100> >’
   33 |     typedef typename turf::util::BestFit<Key>::Unsigned Hash;
      |                                                         ^~~~
In file included from /path/to/project/junction/junction/details/Leapfrog.h:20,
                 from /path/to/project/junction/junction/ConcurrentMap_Leapfrog.h:17,
                 from /path/to/project/main.cpp:2:
/path/to/project/turf/turf/Util.h:22:8: note: declaration of ‘struct turf::util::BestFit<std::bitset<100> >’
   22 | struct BestFit;
      |        ^~~~~~~
In file included from /path/to/project/junction/junction/ConcurrentMap_Leapfrog.h:17,
                 from /path/to/project/main.cpp:2:
/path/to/project/junction/junction/details/Leapfrog.h: In instantiation of ‘static junction::details::Leapfrog<Map>::Table* junction::details::Leapfrog<Map>::Table::create(turf::intTypes::ureg) [with Map = junction::ConcurrentMap_Leapfrog<std::bitset<100>, Foo*>; turf::intTypes::ureg = long long unsigned int]’:
/path/to/project/junction/junction/ConcurrentMap_Leapfrog.h:40:97:   required from ‘junction::ConcurrentMap_Leapfrog<K, V, KT, VT>::ConcurrentMap_Leapfrog(turf::intTypes::ureg) [with K = std::bitset<100>; V = Foo*; KT = junction::DefaultKeyTraits<std::bitset<100> >; VT = junction::DefaultValueTraits<Foo*>; turf::intTypes::ureg = long long unsigned int]’
/path/to/project/main.cpp:8:19:   required from here
/path/to/project/junction/junction/details/Leapfrog.h:81:37: error: ‘struct junction::details::Leapfrog<junction::ConcurrentMap_Leapfrog<std::bitset<100>, Foo*> >::Cell’ has no member named ‘hash’
   81 |                     group->cells[j].hash.storeNonatomic(KeyTraits::NullHash);
      |                     ~~~~~~~~~~~~~~~~^~~~
In file included from /path/to/project/junction/junction/details/Leapfrog.h:21,
                 from /path/to/project/junction/junction/ConcurrentMap_Leapfrog.h:17,
                 from /path/to/project/main.cpp:2:
/path/to/project/junction/junction/MapTraits.h: In instantiation of ‘struct junction::DefaultKeyTraits<std::bitset<100> >’:
/path/to/project/junction/junction/details/Leapfrog.h:81:21:   required from ‘static junction::details::Leapfrog<Map>::Table* junction::details::Leapfrog<Map>::Table::create(turf::intTypes::ureg) [with Map = junction::ConcurrentMap_Leapfrog<std::bitset<100>, Foo*>; turf::intTypes::ureg = long long unsigned int]’
/path/to/project/junction/junction/ConcurrentMap_Leapfrog.h:40:97:   required from ‘junction::ConcurrentMap_Leapfrog<K, V, KT, VT>::ConcurrentMap_Leapfrog(turf::intTypes::ureg) [with K = std::bitset<100>; V = Foo*; KT = junction::DefaultKeyTraits<std::bitset<100> >; VT = junction::DefaultValueTraits<Foo*>; turf::intTypes::ureg = long long unsigned int]’
/path/to/project/main.cpp:8:19:   required from here
/path/to/project/junction/junction/MapTraits.h:24:55: error: invalid use of incomplete type ‘struct turf::util::BestFit<std::bitset<100> >’
   24 |     typedef typename turf::util::BestFit<T>::Unsigned Hash;
      |                                                       ^~~~
In file included from /path/to/project/junction/junction/details/Leapfrog.h:20,
                 from /path/to/project/junction/junction/ConcurrentMap_Leapfrog.h:17,
                 from /path/to/project/main.cpp:2:
/path/to/project/turf/turf/Util.h:22:8: note: declaration of ‘struct turf::util::BestFit<std::bitset<100> >’
   22 | struct BestFit;
      |        ^~~~~~~
In file included from /path/to/project/junction/junction/details/Leapfrog.h:21,
                 from /path/to/project/junction/junction/ConcurrentMap_Leapfrog.h:17,
                 from /path/to/project/main.cpp:2:
/path/to/project/junction/junction/MapTraits.h:25:22: error: ‘constexpr’ needed for in-class initialization of static data member ‘const Key junction::DefaultKeyTraits<std::bitset<100> >::NullKey’ of non-integral type [-fpermissive]
   25 |     static const Key NullKey = Key(0);
      |                      ^~~~~~~
In file included from /path/to/project/junction/junction/ConcurrentMap_Leapfrog.h:17,
                 from /path/to/project/main.cpp:2:
/path/to/project/junction/junction/details/Leapfrog.h: In instantiation of ‘static junction::details::Leapfrog<Map>::Table* junction::details::Leapfrog<Map>::Table::create(turf::intTypes::ureg) [with Map = junction::ConcurrentMap_Leapfrog<std::bitset<100>, Foo*>; turf::intTypes::ureg = long long unsigned int]’:
/path/to/project/junction/junction/ConcurrentMap_Leapfrog.h:40:97:   required from ‘junction::ConcurrentMap_Leapfrog<K, V, KT, VT>::ConcurrentMap_Leapfrog(turf::intTypes::ureg) [with K = std::bitset<100>; V = Foo*; KT = junction::DefaultKeyTraits<std::bitset<100> >; VT = junction::DefaultValueTraits<Foo*>; turf::intTypes::ureg = long long unsigned int]’
/path/to/project/main.cpp:8:19:   required from here
/path/to/project/junction/junction/details/Leapfrog.h:81:21: error: ‘NullHash’ is not a member of ‘junction::details::Leapfrog<junction::ConcurrentMap_Leapfrog<std::bitset<100>, Foo*> >::KeyTraits’ {aka ‘junction::DefaultKeyTraits<std::bitset<100> >’}
   81 |                     group->cells[j].hash.storeNonatomic(KeyTraits::NullHash);
      |                     ^~~~~
make[3]: *** [CMakeFiles/test.dir/build.make:82: CMakeFiles/test.dir/main.cpp.o] Error 1
make[2]: *** [CMakeFiles/Makefile2:136: CMakeFiles/test.dir/all] Error 2
make[1]: *** [CMakeFiles/Makefile2:143: CMakeFiles/test.dir/rule] Error 2
make: *** [Makefile:137: test] Error 2

To my understanding, the error is caused by turf being unable to hash std::bitset. Also, C++11 supports hashing std::bitset and a few other types by default so maybe using std::hash in junction implementation could help. I could submit a PR, if you gave me a bit of guidance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant