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