Skip to content

Using pointer to tuple as key results in compilation errors for lower_bound and upper_bound #9

@rassau

Description

@rassau

Hey,
Encountered another problem when using pointer as key.

Issue:

Setting a std::tuple<uint64_t, uint64_t>* as Key results in compilation errors when calling lower_bound or upper_bound with this key. Given an extractor that takes an std::tuple<uint64_t, uint64_t>* and returns an std::tuple<uint64_t, uint64_t> (with different element order in my application)

Reproducibility:

Compiled with g++ test.cpp -o test
Using g++ (GCC) 15.2.1 20250813 on archlinux

Removing Variant 3 allows compilation.

test.cpp

#include <iostream>
#include <tuple>
#include <vector>
#include <string>

#include <seq/radix_map.hpp>

using schema_t = std::tuple<uint64_t,uint64_t>;


struct extractor_t {
    schema_t operator()(const schema_t* tuple) const { 
        return schema_t{std::get<1>(*tuple), std::get<0>(*tuple)}; 
    }
  };

void show_all(seq::radix_map<schema_t*, size_t, extractor_t>::iterator begin,
              seq::radix_map<schema_t*, size_t, extractor_t>::iterator end) {
    for (auto it = begin; it != end; ++it) {
        std::cout << "Tuple: (" << std::get<0>(*(it->first)) << "," << std::get<1>(*(it->first)) << ") -> " << it->second << std::endl;
    }
}

int main(int, char**) {
    seq::radix_map<schema_t*, size_t, extractor_t> tuples;
    extractor_t my_extractor;
    schema_t my_tuple = schema_t{0,1};
    tuples.insert(std::make_pair(&my_tuple,1));
    // is stored in order (1,0) because schema_t* is given => applying extractor_t to get inner_key
    std::cout << "All tuples in the index:" << std::endl;
    for (auto it : tuples) {
        std::cout << "Tuple: (" << std::get<0>(*(it.first)) << "," << std::get<1>(*(it.first)) << ") -> " << it.second << std::endl;
    }
    std::cout << "===============================" << std::endl;

    // Works CORRECT: schema_t is given => equal to radix_map::radix_key_type 
    // => no extractor applied => no result found (as only the inner key (1,0) is inserted)
    std::cout << "Variant 0:" << std::endl;
    seq::radix_map<schema_t*, size_t, extractor_t>::iterator lower_0 = tuples.lower_bound(my_tuple);
    seq::radix_map<schema_t*, size_t, extractor_t>::iterator upper_0 = tuples.upper_bound(my_tuple);
    show_all(lower_0, upper_0);
    std::cout << "===============================" << std::endl;

    // Works CORRECT: schema_t is given => equal to radix_map::radix_key_type 
    // => no extractor applied => but we applied the constructor before so the tuple is reordered to (1,0) => result found
    std::cout << "Variant 1:" << std::endl;
    schema_t to_test_tuple = my_extractor(&my_tuple);
    std::cout << "To test tuple: (" << std::get<0>(to_test_tuple) << "," << std::get<1>(to_test_tuple) << ")" << std::endl;
    seq::radix_map<schema_t*, size_t, extractor_t>::iterator lower_1 = tuples.lower_bound(to_test_tuple);
    seq::radix_map<schema_t*, size_t, extractor_t>::iterator upper_1 = tuples.upper_bound(to_test_tuple);
    show_all(lower_1, upper_1);
    std::cout << "===============================" << std::endl;

    
    // !Does not compile.!
    // Expected: schema_t* is given => equal to radix_map::Key template argument 
    // => given extractor should be applied => seeking for (1,0) => result found
    std::cout << "Variant 2:" << std::endl;
    seq::radix_map<schema_t*, size_t, extractor_t>::iterator lower_2 = tuples.lower_bound(&my_tuple);
    seq::radix_map<schema_t*, size_t, extractor_t>::iterator upper_2 = tuples.upper_bound(&my_tuple);
    show_all(lower_2, upper_2);
    std::cout << "===============================" << std::endl;

    return 0;
};

Expected output:

All tuples in the index:
Tuple: (0,1) -> 1
===============================
Variant 0:
===============================
Variant 1:
Tuple: (0,1) -> 1
===============================
Variant 2:
Tuple: (0,1) -> 1
===============================

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions