Is there an effective way to assert an constexpr-if branch is executed?

91 Views Asked by At
int f(auto obj) {
    if constexpr (HasFastGetData<decltype(obj)>) {
        return obj.FastGetData();
    } else {
        return obj.GetData();
    }
}

int main() {
    B obj;
    f(obj);
    // How to verify obj.FastGetData(), rather than obj.GetData(), is executed?
}

Take the code above as an example:

  • I have two classes A & B.
  • A has a member function int GetData() and B has a member function int FastGetData().
  • The two functions have the same symantics, but FastGetData is faster than GetData.
  • I want f to differentiate the types of obj for better performance.

I just wonder:

Is there an effective way to unit test my intent?

2

There are 2 best solutions below

1
user12002570 On BEST ANSWER

You can either add static_assert(HasFastGetData<B>) after the call to f or return a std::pair containing the result:

Method 1

f(obj);
//------------vvvvvvvvvvvvvvvvv--->condition of first branch goes here
static_assert(HasFastGetData<B>); //this makes sure that the first branch if taken 


Method 2

You can also return a std::pair(or a custom struct with sensible named members) to check:

std::pair<int,int> f(auto obj) {
    if constexpr (HasFastGetData<decltype(obj)>) {
        return {1, obj.FastGetData()};
    } else {
        return {0,obj.GetData()};
    }
}
int main() {
    B obj;
    std::pair<int, int> result = f(obj);
    if(result.first){} //first branch taken
    else{} 
    
}

1
Nhat Nguyen On

You can use GoogleTest, assert an EXPECT_CALL to the function FastGetData().