@@ -148,33 +148,94 @@ template <class KEY_T>
148148inline std::string key_to_string (KEY_T key) { return std::to_string (key); }
149149
150150
151- template <class Sequence , typename KEY_T>
152- inline
153- auto add_dac_vector (py::module & m, KEY_T key,
154- const char * doc = nullptr )
151+ namespace {
152+
153+ const char dprrr[] = " DPRRR" ;
154+ const char dp[] = " DP" ;
155+
156+ template <typename T, T t, bool = std::is_integral<T>::value>
157+ struct get_vector_type {};
158+
159+ template <typename T, T t>
160+ struct get_vector_type <T, t, true > {
161+ using type = sdsl::dac_vector<t>;
162+ };
163+
164+ template <>
165+ struct get_vector_type <const char *, dp, false > {
166+ using type = sdsl::dac_vector_dp<>;
167+ };
168+
169+ template <>
170+ struct get_vector_type <const char *, dprrr, false > {
171+ using type = sdsl::dac_vector_dp<sdsl::rrr_vector<>>;
172+ };
173+
174+ template <typename T, T t>
175+ using get_vector_type_t = typename get_vector_type<T, t>::type;
176+
177+ } // namespace
178+
179+
180+ class add_dac_vector_functor
155181{
156- auto name = " DirectAccessibleCodesVector" + key_to_string (key);
182+ public:
183+ constexpr add_dac_vector_functor (py::module & m, const char * doc = nullptr ,
184+ const char * doc_dp = nullptr ):
185+ m(m), doc(doc), doc_dp(doc_dp) {}
186+
187+
188+ template <typename KEY_T, KEY_T key>
189+ inline
190+ decltype (auto ) get_vector(std::integral_constant<KEY_T, key>) {
191+ using type = get_vector_type_t <KEY_T, key>;
192+ auto name = " DirectAccessibleCodesVector" + key_to_string (key);
193+
194+ auto cls = py::class_<type>(m, name.c_str ()).def (py::init ());
157195
158- auto cls = py::class_<Sequence>(m, name.c_str ()).def (py::init ());
196+ add_sizes (cls);
197+ add_description (cls);
198+ add_serialization (cls);
199+ add_to_string (cls);
159200
160- add_sizes (cls);
161- add_description (cls);
162- add_serialization (cls);
163- add_to_string (cls);
201+ add_read_access<type>(cls);
202+ add_std_algo<type>(cls);
164203
165- add_read_access<Sequence>(cls);
166- add_std_algo<Sequence>(cls);
204+ if (doc && std::is_integral<KEY_T>::value)
205+ cls.doc () = doc;
206+ else if (doc_dp && !std::is_integral<KEY_T>::value)
207+ cls.doc () = doc_dp;
167208
168- if (doc) {
169- cls.doc () = doc; }
170209
171- cls.def_property_readonly (" levels" , &Sequence ::levels);
210+ cls.def_property_readonly (" levels" , &type ::levels);
172211
173- m.attr (" direct_accessible_codes_vector" ).attr (" __setitem__" )(key, cls);
174- m.attr (" all_compressed_integer_vectors" ).attr (" append" )(cls);
212+ m.attr (" direct_accessible_codes_vector" ).attr (" __setitem__" )(key, cls);
213+ m.attr (" all_compressed_integer_vectors" ).attr (" append" )(cls);
175214
176- return cls;
177- }
215+ return cls;
216+ }
217+
218+ template <typename KEY_T, KEY_T key,
219+ typename std::enable_if<
220+ std::is_integral<KEY_T>::value>::type* dummy = nullptr >
221+ inline
222+ decltype (auto ) operator ()(std::integral_constant<KEY_T, key> t) {
223+ return get_vector (t);
224+ }
225+ template <typename KEY_T, KEY_T key,
226+ typename std::enable_if<
227+ std::is_same<const char *, KEY_T>::value>::type* dummy = nullptr >
228+ inline
229+ decltype (auto ) operator ()(std::integral_constant<KEY_T, key> t) {
230+ return get_vector (t).def (" cost" , &get_vector_type_t <KEY_T, key>::cost,
231+ py::arg (" n" ), py::arg (" m" ));
232+ }
233+
234+ private:
235+ py::module & m;
236+ const char * doc;
237+ const char * doc_dp;
238+ };
178239
179240
180241auto add_encoded_vectors (py::module & m)
@@ -186,20 +247,17 @@ auto add_encoded_vectors(py::module& m)
186247
187248 auto enc_classes = for_each_in_tuple (coders, add_enc_coders_functor (m));
188249 auto vlc_classes = for_each_in_tuple (coders, add_vlc_coders_functor (m));
189- auto dac_classes = std::make_tuple (
190- add_dac_vector<sdsl::dac_vector<4 >>(m, 4 , doc_dac_vector),
191- add_dac_vector<sdsl::dac_vector<8 >>(m, 8 , doc_dac_vector),
192- add_dac_vector<sdsl::dac_vector<16 >>(m, 16 , doc_dac_vector),
193- add_dac_vector<sdsl::dac_vector<63 >>(m, 63 , doc_dac_vector),
194- add_dac_vector<sdsl::dac_vector_dp<>>(m, " DP" , doc_dac_vector_dp)
195- .def (" cost" , &sdsl::dac_vector_dp<>::cost,
196- py::arg (" n" ), py::arg (" m" )),
197- add_dac_vector<
198- sdsl::dac_vector_dp<
199- sdsl::rrr_vector<>>>(m, " DPRRR" , doc_dac_vector_dp)
200- .def (" cost" , &sdsl::dac_vector_dp<sdsl::rrr_vector<>>::cost,
201- py::arg (" n" ), py::arg (" m" ))
202- );
250+
251+ using dac_params = std::tuple<
252+ std::integral_constant<size_t , 4 >,
253+ std::integral_constant<size_t , 8 >,
254+ std::integral_constant<size_t , 16 >,
255+ std::integral_constant<size_t , 63 >,
256+ std::integral_constant<const char *, dp>,
257+ std::integral_constant<const char *, dprrr>
258+ >;
259+ auto dac_classes = for_each_in_tuple (dac_params (),
260+ add_dac_vector_functor (m, doc_dac_vector, doc_dac_vector_dp));
203261
204262 m.attr (" DACVector" ) = m.attr (" DirectAccessibleCodesVector4" );
205263 m.attr (" DirectAccessibleCodesVector" ) = m.attr (
0 commit comments