Files
geant4/source/processes/hadronic/models/lend/include/MCGIDI_string.hpp
2025-12-05 08:54:02 +01:00

175 lines
6.5 KiB
C++

/*
# <<BEGIN-copyright>>
# Copyright 2019, Lawrence Livermore National Security, LLC.
# This file is part of the gidiplus package (https://github.com/LLNL/gidiplus).
# gidiplus is licensed under the MIT license (see https://opensource.org/licenses/MIT).
# SPDX-License-Identifier: MIT
# <<END-copyright>>
*/
#ifndef MCGIDI_STRING_HPP
#define MCGIDI_STRING_HPP
/* Modified from Karsten Burger's version 2017
* Made changes to make it more compatible with GPUs.
* Allow for data to be initialized to nullptr.
*
* Modified from public domain software:
* Karsten Burger 2014
*
* Sourceforge project "Simple C++ String Class"
* http://sourceforge.net/projects/simplecstringclass/
* This a simple C++ string class based on class my_string by
* Christian Stigen Larsen, 2007, http://csl.name/programming/my_string/
*
* It only uses the C-string functions and is thus independent of the
* standard C++ library.
*
* It is public domain, in the hope, that you find it useful.
* Please note that there is no guarantee of any kind: it is supplied
* without any warranty; without even the implied warranty of
* merchantability or fitness for a particular purpose.
*
* You can probably replace std::string with this one in many
* cases, but a lot of stuff is missing, and I would recommend
* you stick to std::string anyway.
*
* I want to point out that there is nothing fancy about this class.
* It keeps every string in its own buffer, and copies as often as
* needed.
* The data always contains a trailing NUL char.
*
* However, I believe that is a good approach. For instance, it
* uses malloc rather than new, which makes it possible to use
* realloc. On many systems, realloc will try to use up "invisible"
* space that was used by malloc to pad a string for memory alignment.
* That makes it potentially fast for small concatenations.
*
* I don't propose to use this class for anything practical, since
* we already have std::string, but it may be an interesting read
* for C++ novices at the very least. Also, additional functions can
* easily be expanded.
*
* Also I met a case, where I had to avoid std::string because of
* link problems with an application using mixed libraries, especially
* one compiled with an old Intel compiler icc 7.
*
* Bugs/suggestions to info [at) dr-burger ]dot[ com
* or via the Sourceforge project page.
*/
#include <sys/types.h> // size_t
#include <stdexcept>
#include <LUPI_declareMacro.hpp>
/** @brief Simple C++ string class, useful as replacement for
std::string if this cannot be used, or just for fun.
*/
namespace MCGIDI {
class String
{
char* p; ///< The data
size_t allocated_; ///< The allocated memory size (including trailing NUL)
size_t size_; ///< The currently used memory size (excluding trailing NUL)
public:
typedef size_t size_type;
static const size_type npos;
LUPI_HOST_DEVICE String();
LUPI_HOST_DEVICE ~String();
LUPI_HOST_DEVICE String(const String&);
LUPI_HOST_DEVICE String(const char*);
LUPI_HOST_DEVICE String& operator=(const char*);
LUPI_HOST_DEVICE String& operator=(const String&);
LUPI_HOST_DEVICE String& operator+=(const String&);
LUPI_HOST_DEVICE String& operator+=(const char*);
LUPI_HOST_DEVICE String& operator+=(char);
LUPI_HOST_DEVICE void push_back(char);
friend String
LUPI_HOST_DEVICE operator+(const String& lhs, const String& rhs);
LUPI_HOST_DEVICE bool operator==(const char*) const;
LUPI_HOST_DEVICE bool operator==(const String&) const;
LUPI_HOST_DEVICE void clear(); // set string to empty string (memory remains reserved)
LUPI_HOST_DEVICE void clearMemory(); // set string to empty string (memory is free'd)
LUPI_HOST_DEVICE size_type size() const { return size_; } ///< size without terminating NUL
LUPI_HOST_DEVICE size_type length() const { return size_; } ///< as size()
// size if fully used
LUPI_HOST_DEVICE size_type capacity() const { return allocated_-1; }
// 8 byte alligned size
LUPI_HOST_DEVICE size_t internalSize() const {
size_t delta = allocated_;
size_t sub = delta % 8;
if (sub != 0) delta += (8-sub);
return delta * sizeof(char);
}
LUPI_HOST_DEVICE bool empty() const { return size_ == 0; }
LUPI_HOST_DEVICE const char* c_str() const { return p; } ///< raw data
/** Reserve internal string memory so that n characters can be put into the
string (plus 1 for the NUL char). If there is already enough memory,
nothing happens, if not, the memory will be realloated to exactly this
amount.
*/
LUPI_HOST_DEVICE void reserve( size_type n, char ** address = nullptr);
/** Resize string. If n is less than the current size, the string will be truncated.
If n is larger, then the memory will be reallocated to exactly this amount, and
the additional characters will be NUL characters.
*/
LUPI_HOST_DEVICE void resize( size_type n, char ** address = nullptr);
/** Resize string. If n is less than the current size, the string will be truncated.
If n is larger, then the memory will be reallocated to exactly this amount, and
the additional characters will be c characters.
*/
LUPI_HOST_DEVICE void resize( size_type n, char c, char ** address = nullptr);
/// swap contents
LUPI_HOST_DEVICE void swap( String& );
LUPI_HOST_DEVICE String substr(const size_type pos, size_type length) const;
// unchecked access:
LUPI_HOST_DEVICE char& operator[](const size_type i) { return p[i]; }
LUPI_HOST_DEVICE char operator[](const size_type i) const { return p[i]; }
// checked access:
LUPI_HOST_DEVICE char& at(const size_type i);
LUPI_HOST_DEVICE char at(const size_type i) const;
/// erase len characters at position pos
LUPI_HOST_DEVICE String& erase(size_type pos, size_type len);
/// Append n characters of a string
LUPI_HOST_DEVICE String& append(const char* str, size_type n);
LUPI_HOST_DEVICE int compare( size_type pos, size_type len, const String& str ) const;
LUPI_HOST_DEVICE int compare( size_type pos, size_type len, const char* str ) const;
private:
// reallocate the internal memory
LUPI_HOST_DEVICE void my_realloc( size_type n, char ** address = nullptr);
LUPI_HOST_DEVICE char* strdup_never_null(const char* other);
};
// class
LUPI_HOST_DEVICE bool operator<(const String&, const String&);
}
#endif