tvm
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
string.h
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 
24 #ifndef TVM_RUNTIME_CONTAINER_STRING_H_
25 #define TVM_RUNTIME_CONTAINER_STRING_H_
26 
27 #include <dmlc/endian.h>
29 #include <tvm/runtime/logging.h>
30 #include <tvm/runtime/memory.h>
31 #include <tvm/runtime/object.h>
32 
33 #include <algorithm>
34 #include <cstddef>
35 #include <cstring>
36 #include <initializer_list>
37 #include <memory>
38 #include <string>
39 #include <string_view>
40 #include <type_traits>
41 #include <unordered_map>
42 #include <utility>
43 #include <vector>
44 
45 namespace tvm {
46 namespace runtime {
47 
48 // Forward declare TVMArgValue
49 class TVMArgValue;
50 
52 class StringObj : public Object {
53  public:
55  const char* data;
56 
58  uint64_t size;
59 
60  static constexpr const uint32_t _type_index = TypeIndex::kRuntimeString;
61  static constexpr const char* _type_key = "runtime.String";
63 
64  private:
66  class FromStd;
67 
68  friend class String;
69 };
70 
97 class String : public ObjectRef {
98  public:
102  String() : String(std::string()) {}
111  String(std::string other); // NOLINT(*)
112 
118  String(const char* other) // NOLINT(*)
119  : String(std::string(other)) {}
120 
124  String(std::nullptr_t) // NOLINT(*)
125  : ObjectRef(nullptr) {}
126 
133  inline String& operator=(std::string other);
134 
140  inline String& operator=(const char* other);
141 
150  int compare(const String& other) const {
151  return memncmp(data(), other.data(), size(), other.size());
152  }
153 
162  int compare(const std::string& other) const {
163  return memncmp(data(), other.data(), size(), other.size());
164  }
165 
174  int compare(const char* other) const {
175  return memncmp(data(), other, size(), std::strlen(other));
176  }
177 
183  const char* c_str() const { return get()->data; }
184 
190  size_t size() const {
191  const auto* ptr = get();
192  return ptr->size;
193  }
194 
200  size_t length() const { return size(); }
201 
207  bool empty() const { return size() == 0; }
208 
215  char at(size_t pos) const {
216  if (pos < size()) {
217  return data()[pos];
218  } else {
219  throw std::out_of_range("tvm::String index out of bounds");
220  }
221  }
222 
228  const char* data() const { return get()->data; }
229 
235  operator std::string() const { return std::string{get()->data, size()}; }
236 
242  inline static bool CanConvertFrom(const TVMArgValue& val);
243 
250  static uint64_t StableHashBytes(const char* data, size_t size) {
251  const constexpr uint64_t kMultiplier = 1099511628211ULL;
252  const constexpr uint64_t kMod = 2147483647ULL;
253  union Union {
254  uint8_t a[8];
255  uint64_t b;
256  } u;
257  static_assert(sizeof(Union) == sizeof(uint64_t), "sizeof(Union) != sizeof(uint64_t)");
258  const char* it = data;
259  const char* end = it + size;
260  uint64_t result = 0;
261  for (; it + 8 <= end; it += 8) {
262  if (DMLC_IO_NO_ENDIAN_SWAP) {
263  u.a[0] = it[0];
264  u.a[1] = it[1];
265  u.a[2] = it[2];
266  u.a[3] = it[3];
267  u.a[4] = it[4];
268  u.a[5] = it[5];
269  u.a[6] = it[6];
270  u.a[7] = it[7];
271  } else {
272  u.a[0] = it[7];
273  u.a[1] = it[6];
274  u.a[2] = it[5];
275  u.a[3] = it[4];
276  u.a[4] = it[3];
277  u.a[5] = it[2];
278  u.a[6] = it[1];
279  u.a[7] = it[0];
280  }
281  result = (result * kMultiplier + u.b) % kMod;
282  }
283  if (it < end) {
284  u.b = 0;
285  uint8_t* a = u.a;
286  if (it + 4 <= end) {
287  a[0] = it[0];
288  a[1] = it[1];
289  a[2] = it[2];
290  a[3] = it[3];
291  it += 4;
292  a += 4;
293  }
294  if (it + 2 <= end) {
295  a[0] = it[0];
296  a[1] = it[1];
297  it += 2;
298  a += 2;
299  }
300  if (it + 1 <= end) {
301  a[0] = it[0];
302  it += 1;
303  a += 1;
304  }
305  if (!DMLC_IO_NO_ENDIAN_SWAP) {
306  std::swap(u.a[0], u.a[7]);
307  std::swap(u.a[1], u.a[6]);
308  std::swap(u.a[2], u.a[5]);
309  std::swap(u.a[3], u.a[4]);
310  }
311  result = (result * kMultiplier + u.b) % kMod;
312  }
313  return result;
314  }
315 
317 
318  private:
329  static int memncmp(const char* lhs, const char* rhs, size_t lhs_count, size_t rhs_count);
330 
341  static String Concat(const char* lhs, size_t lhs_size, const char* rhs, size_t rhs_size) {
342  std::string ret(lhs, lhs_size);
343  ret.append(rhs, rhs_size);
344  return String(ret);
345  }
346 
347  // Overload + operator
348  friend String operator+(const String& lhs, const String& rhs);
349  friend String operator+(const String& lhs, const std::string& rhs);
350  friend String operator+(const std::string& lhs, const String& rhs);
351  friend String operator+(const String& lhs, const char* rhs);
352  friend String operator+(const char* lhs, const String& rhs);
353 
355 };
356 
359  public:
368  explicit FromStd(std::string other) : data_container{other} {}
369 
370  private:
372  std::string data_container;
373 
374  friend class String;
375 };
376 
377 inline String::String(std::string other) {
378  auto ptr = make_object<StringObj::FromStd>(std::move(other));
379  ptr->size = ptr->data_container.size();
380  ptr->data = ptr->data_container.data();
381  data_ = std::move(ptr);
382 }
383 
384 inline String& String::operator=(std::string other) {
385  String replace{std::move(other)};
386  data_.swap(replace.data_);
387  return *this;
388 }
389 
390 inline String& String::operator=(const char* other) { return operator=(std::string(other)); }
391 
392 inline String operator+(const String& lhs, const String& rhs) {
393  size_t lhs_size = lhs.size();
394  size_t rhs_size = rhs.size();
395  return String::Concat(lhs.data(), lhs_size, rhs.data(), rhs_size);
396 }
397 
398 inline String operator+(const String& lhs, const std::string& rhs) {
399  size_t lhs_size = lhs.size();
400  size_t rhs_size = rhs.size();
401  return String::Concat(lhs.data(), lhs_size, rhs.data(), rhs_size);
402 }
403 
404 inline String operator+(const std::string& lhs, const String& rhs) {
405  size_t lhs_size = lhs.size();
406  size_t rhs_size = rhs.size();
407  return String::Concat(lhs.data(), lhs_size, rhs.data(), rhs_size);
408 }
409 
410 inline String operator+(const char* lhs, const String& rhs) {
411  size_t lhs_size = std::strlen(lhs);
412  size_t rhs_size = rhs.size();
413  return String::Concat(lhs, lhs_size, rhs.data(), rhs_size);
414 }
415 
416 inline String operator+(const String& lhs, const char* rhs) {
417  size_t lhs_size = lhs.size();
418  size_t rhs_size = std::strlen(rhs);
419  return String::Concat(lhs.data(), lhs_size, rhs, rhs_size);
420 }
421 
422 // Overload < operator
423 inline bool operator<(const String& lhs, const std::string& rhs) { return lhs.compare(rhs) < 0; }
424 
425 inline bool operator<(const std::string& lhs, const String& rhs) { return rhs.compare(lhs) > 0; }
426 
427 inline bool operator<(const String& lhs, const String& rhs) { return lhs.compare(rhs) < 0; }
428 
429 inline bool operator<(const String& lhs, const char* rhs) { return lhs.compare(rhs) < 0; }
430 
431 inline bool operator<(const char* lhs, const String& rhs) { return rhs.compare(lhs) > 0; }
432 
433 // Overload > operator
434 inline bool operator>(const String& lhs, const std::string& rhs) { return lhs.compare(rhs) > 0; }
435 
436 inline bool operator>(const std::string& lhs, const String& rhs) { return rhs.compare(lhs) < 0; }
437 
438 inline bool operator>(const String& lhs, const String& rhs) { return lhs.compare(rhs) > 0; }
439 
440 inline bool operator>(const String& lhs, const char* rhs) { return lhs.compare(rhs) > 0; }
441 
442 inline bool operator>(const char* lhs, const String& rhs) { return rhs.compare(lhs) < 0; }
443 
444 // Overload <= operator
445 inline bool operator<=(const String& lhs, const std::string& rhs) { return lhs.compare(rhs) <= 0; }
446 
447 inline bool operator<=(const std::string& lhs, const String& rhs) { return rhs.compare(lhs) >= 0; }
448 
449 inline bool operator<=(const String& lhs, const String& rhs) { return lhs.compare(rhs) <= 0; }
450 
451 inline bool operator<=(const String& lhs, const char* rhs) { return lhs.compare(rhs) <= 0; }
452 
453 inline bool operator<=(const char* lhs, const String& rhs) { return rhs.compare(lhs) >= 0; }
454 
455 // Overload >= operator
456 inline bool operator>=(const String& lhs, const std::string& rhs) { return lhs.compare(rhs) >= 0; }
457 
458 inline bool operator>=(const std::string& lhs, const String& rhs) { return rhs.compare(lhs) <= 0; }
459 
460 inline bool operator>=(const String& lhs, const String& rhs) { return lhs.compare(rhs) >= 0; }
461 
462 inline bool operator>=(const String& lhs, const char* rhs) { return lhs.compare(rhs) >= 0; }
463 
464 inline bool operator>=(const char* lhs, const String& rhs) { return rhs.compare(rhs) <= 0; }
465 
466 // Overload == operator
467 inline bool operator==(const String& lhs, const std::string& rhs) { return lhs.compare(rhs) == 0; }
468 
469 inline bool operator==(const std::string& lhs, const String& rhs) { return rhs.compare(lhs) == 0; }
470 
471 inline bool operator==(const String& lhs, const String& rhs) { return lhs.compare(rhs) == 0; }
472 
473 inline bool operator==(const String& lhs, const char* rhs) { return lhs.compare(rhs) == 0; }
474 
475 inline bool operator==(const char* lhs, const String& rhs) { return rhs.compare(lhs) == 0; }
476 
477 // Overload != operator
478 inline bool operator!=(const String& lhs, const std::string& rhs) { return lhs.compare(rhs) != 0; }
479 
480 inline bool operator!=(const std::string& lhs, const String& rhs) { return rhs.compare(lhs) != 0; }
481 
482 inline bool operator!=(const String& lhs, const String& rhs) { return lhs.compare(rhs) != 0; }
483 
484 inline bool operator!=(const String& lhs, const char* rhs) { return lhs.compare(rhs) != 0; }
485 
486 inline bool operator!=(const char* lhs, const String& rhs) { return rhs.compare(lhs) != 0; }
487 
488 inline std::ostream& operator<<(std::ostream& out, const String& input) {
489  out.write(input.data(), input.size());
490  return out;
491 }
492 
493 inline int String::memncmp(const char* lhs, const char* rhs, size_t lhs_count, size_t rhs_count) {
494  if (lhs == rhs && lhs_count == rhs_count) return 0;
495 
496  for (size_t i = 0; i < lhs_count && i < rhs_count; ++i) {
497  if (lhs[i] < rhs[i]) return -1;
498  if (lhs[i] > rhs[i]) return 1;
499  }
500  if (lhs_count < rhs_count) {
501  return -1;
502  } else if (lhs_count > rhs_count) {
503  return 1;
504  } else {
505  return 0;
506  }
507 }
508 
509 inline size_t ObjectHash::operator()(const ObjectRef& a) const {
510  if (const auto* str = a.as<StringObj>()) {
511  return String::StableHashBytes(str->data, str->size);
512  }
513  return ObjectPtrHash()(a);
514 }
515 
516 inline bool ObjectEqual::operator()(const ObjectRef& a, const ObjectRef& b) const {
517  if (a.same_as(b)) {
518  return true;
519  }
520  if (const auto* str_a = a.as<StringObj>()) {
521  if (const auto* str_b = b.as<StringObj>()) {
522  return String::memncmp(str_a->data, str_b->data, str_a->size, str_b->size) == 0;
523  }
524  }
525  return false;
526 }
527 } // namespace runtime
528 
529 // expose the functions to the root namespace.
530 using runtime::String;
531 using runtime::StringObj;
532 } // namespace tvm
533 
534 namespace std {
535 
536 template <>
537 struct hash<::tvm::runtime::String> {
538  std::size_t operator()(const ::tvm::runtime::String& str) const {
539  return ::tvm::runtime::String::StableHashBytes(str.data(), str.size());
540  }
541 };
542 } // namespace std
543 
544 #endif // TVM_RUNTIME_CONTAINER_STRING_H_
Base class of all object reference.
Definition: object.h:520
const Object * get() const
Definition: object.h:555
ObjectPtr< Object > data_
Internal pointer that backs the reference.
Definition: object.h:606
const ObjectType * as() const
Try to downcast the internal Object to a raw pointer of a corresponding type.
Definition: object.h:911
bool same_as(const ObjectRef &other) const
Comparator.
Definition: object.h:531
base class of all object containers.
Definition: object.h:172
An object representing string moved from std::string.
Definition: string.h:358
FromStd(std::string other)
Construct a new FromStd object.
Definition: string.h:368
An object representing string. It's POD type.
Definition: string.h:52
const char * data
The pointer to string data.
Definition: string.h:55
static constexpr const char * _type_key
Definition: string.h:61
uint64_t size
The length of the string object.
Definition: string.h:58
static constexpr const uint32_t _type_index
Definition: string.h:60
TVM_DECLARE_FINAL_OBJECT_INFO(StringObj, Object)
Reference to string objects.
Definition: string.h:97
int compare(const char *other) const
Compares this to other.
Definition: string.h:174
static bool CanConvertFrom(const TVMArgValue &val)
Check if a TVMArgValue can be converted to String, i.e. it can be std::string or String.
Definition: packed_func.h:2675
friend String operator+(const String &lhs, const String &rhs)
Definition: string.h:392
String & operator=(std::string other)
Change the value the reference object points to.
Definition: string.h:384
const char * data() const
Return the data pointer.
Definition: string.h:228
String(const char *other)
Construct a new String object.
Definition: string.h:118
size_t length() const
Return the length of the string.
Definition: string.h:200
static uint64_t StableHashBytes(const char *data, size_t size)
Hash the binary bytes.
Definition: string.h:250
bool empty() const
Retun if the string is empty.
Definition: string.h:207
char at(size_t pos) const
Read an element.
Definition: string.h:215
int compare(const std::string &other) const
Compares this String object to other.
Definition: string.h:162
String()
Construct an empty string.
Definition: string.h:102
const char * c_str() const
Returns a pointer to the char array in the string.
Definition: string.h:183
String(std::nullptr_t)
Construct a new null object.
Definition: string.h:124
int compare(const String &other) const
Compares this String object to other.
Definition: string.h:150
size_t size() const
Return the length of the string.
Definition: string.h:190
TVM_DEFINE_NOTNULLABLE_OBJECT_REF_METHODS(String, ObjectRef, StringObj)
Runtime memory management.
IntSet Union(const Array< IntSet > &sets)
Create a union set of all sets, possibly relaxed.
bool operator<(const String &lhs, const std::string &rhs)
Definition: string.h:423
String operator+(const String &lhs, const String &rhs)
Definition: string.h:392
Array< T > Concat(Array< T > lhs, const Array< T > &rhs)
Concat two Arrays.
Definition: array.h:899
bool operator!=(const String &lhs, const std::string &rhs)
Definition: string.h:478
bool operator<=(const String &lhs, const std::string &rhs)
Definition: string.h:445
bool operator>=(const String &lhs, const std::string &rhs)
Definition: string.h:456
bool operator==(const String &lhs, const std::string &rhs)
Definition: string.h:467
std::ostream & operator<<(std::ostream &os, const ObjectRef &n)
Definition: repr_printer.h:97
bool operator>(const String &lhs, const std::string &rhs)
Definition: string.h:434
Performance counters for profiling via the PAPI library.
Definition: analyzer.h:36
PrimExpr ret(PrimExpr value, Span span=Span())
Return the value.
A managed object in the TVM runtime.
Base utilities for common POD(plain old data) container types.
String-aware ObjectRef hash functor.
Definition: base.h:49
bool operator()(const ObjectRef &a, const ObjectRef &b) const
Check if the two ObjectRef are equal.
Definition: string.h:516
size_t operator()(const ObjectRef &a) const
Calculate the hash code of an ObjectRef.
Definition: string.h:509
ObjectRef hash functor.
Definition: object.h:656
@ kRuntimeString
runtime::String.
Definition: object.h:66