//===--- OwnedString.h - String storage -------------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
//  This file defines the 'OwnedString' storage wrapper, which can hold its own
//  unique copy of a string, or merely hold a reference to some point in a
//  source buffer, which is assumed to live at least as long as a value of this
//  type.
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_BASIC_OWNEDSTRING_H
#define SWIFT_BASIC_OWNEDSTRING_H

#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/TrailingObjects.h"

using llvm::StringRef;

namespace swift {

/// Holds a string - either statically allocated or dynamically allocated
/// and owned by this type.
class OwnedString {
  /// An owner that keeps the buffer of a ref counted \c OwnedString alive.
  class TextOwner final : public llvm::ThreadSafeRefCountedBase<TextOwner>,
                          public llvm::TrailingObjects<TextOwner, char> {
    TextOwner(StringRef Text) {
      std::uninitialized_copy(Text.begin(), Text.end(),
                              getTrailingObjects<char>());
    }

  public:
    static TextOwner *make(StringRef Text) {
      auto size = totalSizeToAlloc<char>(Text.size());
      void *data = ::operator new(size);
      return new (data) TextOwner(Text);
    }

    /// Disable sized deallocation for TextOwner, because it has tail-allocated
    /// data.
    void operator delete(void *p) { ::operator delete(p); }

    const char *getText() const { return getTrailingObjects<char>(); }
  };

  /// The text this owned string represents
  StringRef Text;

  /// In case of a ref counted string an owner that keeps the buffer \c Text
  /// references alive.
  llvm::IntrusiveRefCntPtr<TextOwner> OwnedPtr;

  OwnedString(StringRef Text, llvm::IntrusiveRefCntPtr<TextOwner> OwnedPtr)
      : Text(Text), OwnedPtr(OwnedPtr) {}

public:
  OwnedString() : OwnedString(/*Text=*/StringRef(), /*OwnedPtr=*/nullptr) {}

  /// Create a ref counted \c OwnedString that is initialized with the text of
  /// the given \c StringRef.
  OwnedString(StringRef Str) : OwnedString(makeRefCounted(Str)) {}

  /// Create a ref counted \c OwnedString that is initialized with the text of
  /// the given buffer.
  OwnedString(const char *Str) : OwnedString(StringRef(Str)) {}

  /// Create an \c OwnedString that references the given string. The
  /// \c OwnedString will not take ownership of that buffer and will assume that
  /// the buffer outlives its lifetime.
  static OwnedString makeUnowned(StringRef Str) {
    return OwnedString(Str, /*OwnedPtr=*/nullptr);
  }

  /// Create an \c OwnedString that keeps its contents in a reference counted
  /// buffer. The contents of \p Str will be copied initially and are allowed to
  /// be disposed after the \c OwnedString has been created.
  static OwnedString makeRefCounted(StringRef Str) {
    if (Str.empty()) {
      // Copying an empty string doesn't make sense. Just create an unowned
      // string that points to the empty string.
      return makeUnowned(Str);
    } else {
      llvm::IntrusiveRefCntPtr<TextOwner> OwnedPtr(TextOwner::make(Str));
      // Allocate the StringRef on the stack first.  This is to ensure that the
      // order of evaluation of the arguments is specified.  The specification
      // does not specify the order of evaluation for the arguments.  Itanium
      // chose to evaluate left to right, while Windows evaluates right to left.
      // As such, it is possible that the OwnedPtr has already been `std::move`d
      // by the time that the StringRef is attempted to be created.  In such a
      // case, the offset of the field (+4) is used instead of the pointer to
      // the text, resulting in invalid memory references.
      StringRef S(OwnedPtr->getText(), Str.size());
      return OwnedString(S, std::move(OwnedPtr));
    }
  }

  /// Returns the length of the string in bytes.
  size_t size() const { return Text.size(); }

  /// Returns true if the length is 0.
  bool empty() const { return size() == 0; }

  /// Returns a StringRef to the underlying data. No copy is made and no
  /// ownership changes take place.
  StringRef str() const { return Text; }

  bool operator==(const OwnedString &Right) const {
    return str() == Right.str();
  }
};

} // end namespace swift

#endif // SWIFT_BASIC_OWNEDSTRING_H
