LINUX.ORG.RU

История изменений

Исправление MOPKOBKA, (текущая версия) :

Интересная задача, придумал такое.

#include <initializer_list>
#include <cstring>
#include <cstdio>
#include <functional>

inline __attribute__((always_inline)) void strarray (
    std::initializer_list<std::initializer_list<const char*>> strarr, 
    auto f
) {
    size_t fullsize = sizeof(const char *) * strarr.size();
    for (auto subarr : strarr) {
        for (auto str : subarr) fullsize += strlen(str);
        fullsize += 1;
    }
    char buff[fullsize];
    char **pe = (char**)buff;
    char *pi = buff + sizeof(const char *) * strarr.size();
    for (auto subarr : strarr) {
        *pe++ = pi;
        for (auto str : subarr) {
            size_t len = strlen(str);
            memcpy(pi, str, len + 1);
            pi += len;
        }
        pi++;
    }
    return f((char**)buff);
}

void c_function(const char * const* arr, int n) {
    for (int i = 0; i < n; ++i) puts(arr[i]);
}

int main() {
    strarray({
        {"Hello", "World", "!"},
        {"Concat", "String"}
    }, [](char **arr) { c_function(arr, 2); });
}
Да, тут memcpy, заполнение массива, но без копирования совсем не обойтись, строки по другому не совместить.

Не нашел способа сделать alloc из вызывающей функции, поэтому пошел обратным путем, и передаю массив во внутреннюю функцию, лямбду.

Исходная версия MOPKOBKA, :

Интересная задача, придумал такое.

#include <initializer_list>
#include <cstring>
#include <cstdio>
#include <functional>

inline __attribute__((always_inline)) void strarray (
    std::initializer_list<std::initializer_list<const char*>> strarr, 
    auto f
) {
    size_t fullsize = sizeof(const char *) * strarr.size();
    for (auto subarr : strarr) {
        for (auto str : subarr) fullsize += strlen(str);
        fullsize += 1;
    }
    char buff[fullsize];
    char **pe = (char**)buff;
    char *pi = buff + sizeof(const char *) * strarr.size();
    for (auto subarr : strarr) {
        *pe++ = pi;
        for (auto str : subarr) {
            size_t len = strlen(str);
            memcpy(pi, str, len + 1);
            pi += len;
        }
        pi++;
    }
    return f((char**)buff);
}

void c_function(const char * const* arr, int n) {
    for (int i = 0; i < n; ++i) puts(arr[i]);
}

int main() {
    strarray({
        {"Hello", "World", "!"},
        {"Concat", "String"}
    }, [](char **arr) { c_function(arr, 2); });
}
Да, тут memcpy, заполнение массива, но без копирования совсем не обойтись, строки по другому не совместить.