| 400 | using HeapValue = std::unique_ptr<ValueInterface>; |
| 401 | |
| 402 | struct InlineValue { |
| 403 | // We try to size InlineValue so that sizeof(Variant) <= 64 and it can fit |
| 404 | // into the aligned space of a TensorBuffer. |
| 405 | static constexpr int kMaxValueSize = (64 - /*some extra padding=*/16); |
| 406 | |
| 407 | typedef char ValueDataArray[kMaxValueSize]; |
| 408 | alignas(kMaxInlineValueAlignSize) ValueDataArray value_data; |
| 409 | bool has_value = false; |
| 410 | |
| 411 | explicit InlineValue() {} |
| 412 | |
| 413 | InlineValue(const InlineValue& other) noexcept |
| 414 | : has_value(other.has_value) { |
| 415 | if (other.has_value) { |
| 416 | other.AsValueInterface()->CloneInto(AsValueInterface()); |
| 417 | } |
| 418 | } |
| 419 | |
| 420 | InlineValue(InlineValue&& other) noexcept : has_value(other.has_value) { |
| 421 | if (other.has_value) { |
| 422 | other.AsValueInterface()->MoveInto(AsValueInterface()); |
| 423 | other.Cleanup(); |
| 424 | } |
| 425 | } |
| 426 | |
| 427 | void Cleanup() { |
| 428 | // **NOTE** This must be a no-op if the memory representation of |
| 429 | // InlineValue is all zeros, in order to properly interact with |
| 430 | // HeapOrInline::ResetMemory(). |
| 431 | if (has_value) { |
| 432 | // This doesn't actually delete anything on the heap; the delete |
| 433 | // operator of Value<VT> is overridden to do nothing for inline |
| 434 | // values; the side-effect of delete is that the virtual destructor is |
| 435 | // called. |
| 436 | // |
| 437 | // We leave it to callers to overwrite the data buffer in value_data |
| 438 | // with new objects. |
| 439 | delete AsValueInterface(); |
| 440 | } |
| 441 | has_value = false; |
| 442 | } |
| 443 | |
| 444 | InlineValue& operator=(const InlineValue& other) { |
| 445 | if (&other == this) return *this; |
| 446 | Cleanup(); |
| 447 | if (other.has_value) { |
| 448 | other.AsValueInterface()->CloneInto(AsValueInterface()); |
| 449 | } |
| 450 | has_value = other.has_value; |
| 451 | return *this; |
| 452 | } |
| 453 | |
| 454 | InlineValue& operator=(InlineValue&& other) { |
| 455 | if (&other == this) return *this; |
| 456 | if (other.has_value) { |
| 457 | if (has_value && AsValueInterface()->TypeId() == |
| 458 | other.AsValueInterface()->TypeId()) { |
| 459 | other.AsValueInterface()->Swap(AsValueInterface()); |
no test coverage detected