зеркало из https://github.com/microsoft/LightGBM.git
141 строка
4.0 KiB
C++
141 строка
4.0 KiB
C++
/*!
|
|
* Copyright (c) 2020 Microsoft Corporation. All rights reserved.
|
|
* Licensed under the MIT License. See LICENSE file in the project root for license information.
|
|
*
|
|
* Author: Alberto Ferreira
|
|
*/
|
|
#ifndef LIGHTGBM_SWIG_STRING_ARRAY_H_
|
|
#define LIGHTGBM_SWIG_STRING_ARRAY_H_
|
|
|
|
#include <algorithm>
|
|
#include <new>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
/**
|
|
* Container that manages an array of fixed-length strings.
|
|
*
|
|
* To be compatible with SWIG's `various.i` extension module,
|
|
* the array of pointers to char* must be NULL-terminated:
|
|
* [char*, char*, char*, ..., NULL]
|
|
* This implies that the length of this array is bigger
|
|
* by 1 element than the number of char* it stores.
|
|
* I.e., _num_elements == _array.size()-1
|
|
*
|
|
* The class also takes care of allocation of the underlying
|
|
* char* memory.
|
|
*/
|
|
class StringArray {
|
|
public:
|
|
StringArray(size_t num_elements, size_t string_size)
|
|
: _string_size(string_size),
|
|
_array(num_elements + 1, nullptr) {
|
|
_allocate_strings(num_elements, string_size);
|
|
}
|
|
|
|
~StringArray() {
|
|
_release_strings();
|
|
}
|
|
|
|
/**
|
|
* Returns the pointer to the raw array.
|
|
* Notice its size is greater than the number of stored strings by 1.
|
|
*
|
|
* @return char** pointer to raw data (null-terminated).
|
|
*/
|
|
char **data() noexcept {
|
|
return _array.data();
|
|
}
|
|
|
|
/**
|
|
* Return char* from the array of size _string_size+1.
|
|
* Notice the last element in _array is already
|
|
* considered out of bounds.
|
|
*
|
|
* @param index Index of the element to retrieve.
|
|
* @return pointer or nullptr if index is out of bounds.
|
|
*/
|
|
char *getitem(size_t index) noexcept {
|
|
if (_in_bounds(index))
|
|
return _array[index];
|
|
else
|
|
return nullptr;
|
|
}
|
|
|
|
/**
|
|
* Safely copies the full content data
|
|
* into one of the strings in the array.
|
|
* If that is not possible, returns error (-1).
|
|
*
|
|
* @param index index of the string in the array.
|
|
* @param content content to store
|
|
*
|
|
* @return In case index results in out of bounds access,
|
|
* or content + 1 (null-terminator byte) doesn't fit
|
|
* into the target string (_string_size), it errors out
|
|
* and returns -1.
|
|
*/
|
|
int setitem(size_t index, const std::string &content) noexcept {
|
|
if (_in_bounds(index) && content.size() < _string_size) {
|
|
std::strcpy(_array[index], content.c_str()); // NOLINT
|
|
return 0;
|
|
} else {
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return number of stored strings.
|
|
*/
|
|
size_t get_num_elements() noexcept {
|
|
return _array.size() - 1;
|
|
}
|
|
|
|
private:
|
|
/**
|
|
* Returns true if and only if within bounds.
|
|
* Notice that it excludes the last element of _array (NULL).
|
|
*
|
|
* @param index index of the element
|
|
* @return bool true if within bounds
|
|
*/
|
|
bool _in_bounds(size_t index) noexcept {
|
|
return index < get_num_elements();
|
|
}
|
|
|
|
/**
|
|
* Allocate an array of fixed-length strings.
|
|
*
|
|
* Since a NULL-terminated array is required by SWIG's `various.i`,
|
|
* the size of the array is actually `num_elements + 1` but only
|
|
* num_elements are filled.
|
|
*
|
|
* @param num_elements Number of strings to store in the array.
|
|
* @param string_size The size of each string in the array.
|
|
*/
|
|
void _allocate_strings(size_t num_elements, size_t string_size) {
|
|
for (size_t i = 0; i < num_elements; ++i) {
|
|
// Leave space for \0 terminator:
|
|
_array[i] = new (std::nothrow) char[string_size + 1];
|
|
|
|
// Check memory allocation:
|
|
if (!_array[i]) {
|
|
_release_strings();
|
|
throw std::bad_alloc();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Deletes the allocated strings.
|
|
*/
|
|
void _release_strings() noexcept {
|
|
std::for_each(_array.begin(), _array.end(), [](char* c) { delete[] c; });
|
|
}
|
|
|
|
const size_t _string_size;
|
|
std::vector<char*> _array;
|
|
};
|
|
|
|
#endif // LIGHTGBM_SWIG_STRING_ARRAY_H_
|