Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Detecting Instantiation/Calls with or without the constexpr Keyword in C++20 Constructors/Functions

I am currently trying to find a clean way to create a templated bytearray structure that can be initialized differently based on whether its constructor was instantiated with or without the constexpr keyword, And I also want to apply it to other methods and function if possible, I wonder if there is a way to achieve this?

Here is an example of what I want to achieve:

#include <iostream>
#include <cstring>

template<size_t N>
struct bytearray {
    char data[N];
    constexpr bytearray(char val) : data() {
        if constexpr (... is compile time instantiated ...) {
            for (size_t i = 0; i < N; ++i) {
                data[i] = val;
            }    
        } else {
            std::memset(data, val, N);     
        }
    }
};

int main() {
    constexpr bytearray<10> A(7);
    bytearray<10> B(7);
}

So instantiating the A class at compile time will use the for loop, then memcpy if it was not.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

You are looking for if consteval:

    constexpr bytearray(char val) : data() {
        if consteval {
            for (size_t i = 0; i < N; ++i) {
                data[i] = val;
            }    
        } else {
            std::memset(data, val, N);     
        }
    }

This is a C++23 feature. In C++20, you can use std::is_constant_evaluated:

    constexpr bytearray(char val) : data() {
        if (std::is_constant_evaluated()) {
            for (char& byte : data) {
                byte = val;
            }
        } else {
            std::memset(data, val, N);     
        }
    }

Though note in this specific case, the check isn’t necessary. for (size_t i = 0; i < N; ++i) data[i] = val; will be compiled to the same thing as a memset on any compiler worth its salt.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading