@@ -273,6 +273,85 @@ struct RTLIL::IdString
273273 *out += std::to_string (-index_);
274274 }
275275
276+ class const_iterator {
277+ private:
278+ const std::string *prefix;
279+ std::string suffix;
280+ const char *c_str;
281+ int c_str_len;
282+ // When this is INT_MAX it's the generic "end" value.
283+ int index;
284+
285+ public:
286+ using iterator_category = std::forward_iterator_tag;
287+ using value_type = char ;
288+ using difference_type = std::ptrdiff_t ;
289+ using pointer = const char *;
290+ using reference = const char &;
291+
292+ const_iterator (const char *c_str) : prefix(nullptr ), c_str(c_str), c_str_len(strlen(c_str)), index(0 ) {}
293+ const_iterator (const std::string *prefix, int number) :
294+ prefix (prefix), suffix(std::to_string(number)), c_str(nullptr ), c_str_len(0 ), index(0 ) {}
295+ // Construct end-marker
296+ const_iterator () : prefix(nullptr ), c_str(nullptr ), c_str_len(0 ), index(INT_MAX) {}
297+
298+ int size () const {
299+ if (c_str != nullptr )
300+ return c_str_len;
301+ return GetSize (*prefix) + GetSize (suffix);
302+ }
303+
304+ char operator *() const {
305+ if (c_str != nullptr )
306+ return c_str[index];
307+ int prefix_size = GetSize (*prefix);
308+ if (index < prefix_size)
309+ return prefix->at (index);
310+ return suffix[index - prefix_size];
311+ }
312+
313+ const_iterator& operator ++() { ++index; return *this ; }
314+ const_iterator operator ++(int ) { const_iterator result (*this ); ++index; return result; }
315+ const_iterator& operator +=(int i) { index += i; return *this ; }
316+
317+ const_iterator operator +(int add) {
318+ const_iterator result = *this ;
319+ result += add;
320+ return result;
321+ }
322+
323+ bool operator ==(const const_iterator& other) const {
324+ return index == other.index || (other.index == INT_MAX && index == size ())
325+ || (index == INT_MAX && other.index == other.size ());
326+ }
327+ bool operator !=(const const_iterator& other) const {
328+ return !(*this == other);
329+ }
330+ };
331+ const_iterator begin () const {
332+ if (index_ >= 0 ) {
333+ return const_iterator (global_id_storage_.at (index_));
334+ }
335+ return const_iterator (global_negative_id_prefix_storage_.at (index_), -index_);
336+ }
337+ const_iterator end () const {
338+ return const_iterator ();
339+ }
340+
341+ inline bool lt_by_name (const IdString &rhs) const {
342+ const_iterator rhs_it = rhs.begin ();
343+ for (char ch : *this ) {
344+ if (rhs_it == rhs.end ())
345+ return false ;
346+ if (ch < *rhs_it)
347+ return true ;
348+ if (ch > *rhs_it)
349+ return false ;
350+ ++rhs_it;
351+ }
352+ return rhs_it != rhs.end ();
353+ }
354+
276355 inline bool operator <(const IdString &rhs) const {
277356 return index_ < rhs.index_ ;
278357 }
@@ -291,45 +370,81 @@ struct RTLIL::IdString
291370 bool operator !=(const char *rhs) const { return strcmp (c_str (), rhs) != 0 ; }
292371
293372 char operator [](size_t i) const {
294- const char *p = c_str ();
373+ if (index_ >= 0 ) {
374+ const char *p = global_id_storage_.at (index_);
295375#ifndef NDEBUG
296- for (; i != 0 ; i--, p++)
297- log_assert (*p != 0 );
298- return *p;
376+ for (; i != 0 ; i--, p++)
377+ log_assert (*p != 0 );
378+ return *p;
299379#else
300- return *(p + i);
380+ return *(p + i);
301381#endif
382+ }
383+ const std::string &id_start = *global_negative_id_prefix_storage_.at (index_);
384+ if (i < id_start.size ())
385+ return id_start[i];
386+ return std::to_string (-index_).c_str ()[i - id_start.size ()];
302387 }
303388
304389 std::string substr (size_t pos = 0 , size_t len = std::string::npos) const {
305- if (len == std::string::npos || len >= strlen (c_str () + pos))
306- return std::string (c_str () + pos);
307- else
308- return std::string (c_str () + pos, len);
390+ std::string result;
391+ const_iterator it = begin () + pos;
392+ const_iterator end_it = end ();
393+ if (len != std::string::npos && len < it.size () - pos) {
394+ end_it = it + len;
395+ }
396+ std::copy (it, end_it, std::back_inserter (result));
397+ return result;
309398 }
310399
311400 int compare (size_t pos, size_t len, const char * s) const {
312- return strncmp (c_str ()+pos, s, len);
401+ const_iterator it = begin () + pos;
402+ const_iterator end_it = end ();
403+ while (len > 0 && *s != 0 && it != end_it) {
404+ int diff = *it - *s;
405+ if (diff != 0 )
406+ return diff;
407+ ++it;
408+ ++s;
409+ --len;
410+ }
411+ return 0 ;
313412 }
314413
315414 bool begins_with (const char * prefix) const {
316- size_t len = strlen (prefix);
317- if (size () < len) return false ;
318- return compare (0 , len, prefix) == 0 ;
415+ const_iterator it = begin ();
416+ const_iterator end_it = end ();
417+ while (*prefix != 0 ) {
418+ if (it == end_it || *prefix != *it)
419+ return false ;
420+ ++prefix;
421+ ++it;
422+ }
423+ return true ;
319424 }
320425
321426 bool ends_with (const char * suffix) const {
322- size_t len = strlen (suffix);
323- if (size () < len) return false ;
324- return compare (size ()-len, len, suffix) == 0 ;
427+ int suffix_len = strlen (suffix);
428+ const_iterator it = begin ();
429+ int sz = it.size ();
430+ if (suffix_len > sz)
431+ return false ;
432+ it += sz - suffix_len;
433+ while (*suffix != 0 ) {
434+ if (*it != *suffix)
435+ return false ;
436+ ++suffix;
437+ ++it;
438+ }
439+ return true ;
325440 }
326441
327442 bool contains (const char * str) const {
328443 return strstr (c_str (), str);
329444 }
330445
331446 size_t size () const {
332- return strlen ( c_str () );
447+ return begin (). size ( );
333448 }
334449
335450 bool empty () const {
@@ -627,7 +742,7 @@ namespace RTLIL {
627742
628743 struct sort_by_id_str {
629744 bool operator ()(const RTLIL::IdString &a, const RTLIL::IdString &b) const {
630- return strcmp (a. c_str (), b. c_str ()) < 0 ;
745+ return a. lt_by_name (b) ;
631746 }
632747 };
633748
0 commit comments