1 #ifndef _melder_string32_h_ 2 #define _melder_string32_h_ 3 /* melder_string32.h 4 * 5 * Copyright (C) 1992-2019 Paul Boersma 6 * 7 * This code is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or (at 10 * your option) any later version. 11 * 12 * This code is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 15 * See the GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this work. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 using char8 = unsigned char; 22 using char16 = char16_t; 23 using char32 = char32_t; 24 25 /* USAGE: Constant strings. 26 27 For whole null-terminated strings whose contents will not be changed, use conststring32: 28 void writeString (conststring32 text); 29 30 For a pointer to a character in a conststring32, use "const char32 *". 31 This is appropriate if you need to cycle later: 32 const char32 *p = & text [0]; 33 ... 34 p ++; 35 This is also appropriate for character searches: 36 const char32 *semicolonLocation = str32chr (text, U';'); 37 38 For an array of characters, use "const char32 []": 39 void displayCharacters (const char32 characters []); 40 Such an array may or may not be null-terminated. 41 */ 42 using conststring8 = const char *; 43 using conststring16 = const char16 *; 44 using conststringW = const wchar_t *; 45 using conststring32 = const char32 *; 46 47 /* USAGE: Mutable strings. 48 49 For whole null-terminated strings whose contents will be changed, use mutablestring32: 50 void changeCase (mutablestring32 string); 51 52 For a pointer to a character in a mutablestring32, use "char32 *". 53 This is appropriate if you need to cycle later: 54 char32 *p = & string [0]; 55 ... 56 p ++; 57 This is also appropriate for character searches: 58 char32 *semicolonLocation = str32chr (string, U';'); 59 60 For an array of characters that will be changed, use "char32 []": 61 void modifyCodes (char32 codes []); 62 Such an array may or may not be null-terminated. 63 */ 64 using mutablestring8 = char *; 65 using mutablestring16 = char16 *; 66 using mutablestringW = wchar_t *; 67 using mutablestring32 = char32 *; 68 69 #define strequ ! strcmp 70 #define strnequ ! strncmp 71 72 template <class T> 73 class _autostring { 74 T *ptr; 75 public: 76 #if 1 _autostring()77 _autostring () : ptr (nullptr) { 78 //if (Melder_debug == 39) Melder_casual (U"autostring: zero constructor"); 79 } 80 #else 81 _autostring () = default; // explicit default, so that it can be used in a union 82 #endif 83 explicit _autostring (integer length, bool f = false) { 84 our ptr = ( f ? Melder_malloc_f (T, length + 1) : Melder_malloc (T, length + 1) ); 85 our ptr [0] = '\0'; 86 our ptr [length] = '\0'; 87 } 88 //_autostring (T *string) : ptr (string) { 89 //if (Melder_debug == 39) Melder_casual (U"autostring: constructor from C-string ", Melder_pointer (ptr)); 90 //} ~_autostring()91 ~_autostring () { 92 //if (Melder_debug == 39) Melder_casual (U"autostring: entering destructor ptr = ", Melder_pointer (ptr)); 93 if (our ptr) Melder_free (our ptr); 94 //if (Melder_debug == 39) Melder_casual (U"autostring: leaving destructor"); 95 } 96 template <class U> T& operator[] (U i) { 97 return our ptr [i]; 98 } get()99 T * get () const { 100 return our ptr; 101 } 102 #if 0 103 operator T* () const { 104 return our ptr; 105 } 106 #endif 107 /*T ** operator& () { 108 return & our ptr; 109 }*/ transfer()110 T * transfer () { 111 T *tmp = our ptr; 112 our ptr = nullptr; 113 return tmp; 114 } reset()115 void reset () { 116 if (our ptr) Melder_free (our ptr); 117 } resize(int64 newLength)118 void resize (int64 newLength) { 119 T *tmp = (T *) Melder_realloc (our ptr, (newLength + 1) * (int64) sizeof (T)); 120 our ptr = tmp; 121 our ptr [newLength] = '\0'; 122 } 123 _autostring& operator= (const _autostring&) = delete; // disable copy assignment 124 _autostring (_autostring &) = delete; // disable copy constructor 125 template <class Y> _autostring (_autostring<Y> &) = delete; // disable copy constructor 126 explicit operator bool () const noexcept { return !! our ptr; } 127 /* 128 Enable moving. 129 */ _autostring(_autostring && other)130 _autostring (_autostring&& other) noexcept { // enable move constructor 131 our ptr = other.ptr; 132 other.ptr = nullptr; 133 } 134 _autostring& operator= (_autostring&& other) noexcept { // enable move assignment 135 if (& other != this) { 136 if (our ptr) Melder_free (our ptr); 137 our ptr = other.ptr; 138 other.ptr = nullptr; 139 } 140 return *this; 141 } move()142 _autostring&& move () noexcept { 143 return static_cast <_autostring&&> (*this); 144 } _zero_asInUnion()145 void _zero_asInUnion () { 146 our ptr = nullptr; 147 } 148 }; 149 150 typedef _autostring <char> autostring8; 151 typedef _autostring <char16> autostring16; 152 typedef _autostring <wchar_t> autostringW; 153 typedef _autostring <char32> autostring32; 154 155 autostring32 Melder_dup (conststring32 string /* cattable */); 156 autostring32 Melder_dup_f (conststring32 string /* cattable */); 157 158 /* End of file melder_string32.h */ 159 #endif 160