//===--- SwiftNativeNSXXXBase.mm.gyb - Cocoa classes with fast refcounts --===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Classes derived from ObjC bases but that use native swift reference
// counting, layout, and allocation.
//
// These classes declare a native Swift object header and override the
// NSObject methods that do reference counting to use it accordingly.
// We can only do this trick with objc classes that are known not to
// use the storage where Swift places its native object header.  This
// takes care of how the classes are handled from Objective-C code.
//    _NSSwiftArrayBase, _NSSwiftDictionaryBase, _NSSwiftSetBase
//    _NSSwiftSetBase, _NSSwiftStringBase
//
// To trick Swift into using its fast refcounting and allocation
// directly (rather than going through objc_msgSend to arrive at the
// implementations defined here), we define subclasses on the Swift
// side but hide the inheritance relationship from the Swift compiler
// and only establish it dynamically, in the '+ load' method of each
// class defined here.
//
//===----------------------------------------------------------------------===//

#include "swift/Runtime/Config.h"

#if SWIFT_OBJC_INTEROP
#import <Foundation/Foundation.h>
#import <CoreFoundation/CoreFoundation.h>
#include <objc/NSObject.h>
#include <objc/runtime.h>
#include <objc/objc.h>
#include "swift/Runtime/HeapObject.h"
#include "swift/Runtime/Metadata.h"
#include "swift/Runtime/ObjCBridge.h"
#include "llvm/ADT/DenseMap.h"
#include <stdio.h>
#include <stdlib.h>

using namespace swift;

% for Class in ('Array', 'Dictionary', 'Set', 'String', 'Enumerator', 'Data', 'CharacterSet', 'IndexSet'):
SWIFT_RUNTIME_STDLIB_INTERFACE
@interface _SwiftNativeNS${Class}Base : NS${Class}
{
  SWIFT_HEAPOBJECT_NON_OBJC_MEMBERS;
}
@end


@implementation _SwiftNativeNS${Class}Base

- (id)retain {
  auto SELF = reinterpret_cast<HeapObject *>(self);
  swift_retain(SELF);
  return self;
}
- (oneway void)release {
  auto SELF = reinterpret_cast<HeapObject *>(self);
  swift_release(SELF);
}
- (id)autorelease {
  return _objc_rootAutorelease(self);
}

- (BOOL)_tryRetain {
  auto SELF = reinterpret_cast<HeapObject *>(self);
  return (bool)swift_tryRetain(SELF);
}
- (BOOL)_isDeallocating {
  return swift_isDeallocating(reinterpret_cast<HeapObject *>(self));
}
- (BOOL)allowsWeakReference {
  return !swift_isDeallocating(reinterpret_cast<HeapObject *>(self));
}
- (BOOL)retainWeakReference {
  return swift_tryRetain(reinterpret_cast<HeapObject*>(self)) != nullptr;
}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-missing-super-calls"
- (void)dealloc {
  swift_rootObjCDealloc(reinterpret_cast<HeapObject *>(self));
}
#pragma clang diagnostic pop

@end
% end

SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
bool
swift_stdlib_NSObject_isEqual(NSObject *NS_RELEASES_ARGUMENT lhs,
                              NSObject *NS_RELEASES_ARGUMENT rhs) {
  bool Result = (lhs == rhs) || [lhs isEqual:rhs];
  swift_unknownRelease(lhs);
  swift_unknownRelease(rhs);
  return Result;
}

SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
int32_t swift_stdlib_compareNSStringDeterministicUnicodeCollation(
    NSString *NS_RELEASES_ARGUMENT lhs, NSString *NS_RELEASES_ARGUMENT rhs) {
  // 'kCFCompareNonliteral' actually means "normalize to NFD".
  int Result = CFStringCompare((__bridge CFStringRef)lhs,
                               (__bridge CFStringRef)rhs, kCFCompareNonliteral);
  swift_unknownRelease(lhs);
  swift_unknownRelease(rhs);
  return Result;
}

SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
int32_t
swift_stdlib_compareNSStringDeterministicUnicodeCollationPtr(void *Lhs,
                                                             void *Rhs) {
  NSString *lhs = (NSString *)Lhs;
  NSString *rhs = (NSString *)Rhs;

  // 'kCFCompareNonliteral' actually means "normalize to NFD".
  int Result = CFStringCompare((__bridge CFStringRef)lhs,
                               (__bridge CFStringRef)rhs, kCFCompareNonliteral);
  return Result;
}

SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
size_t
swift_stdlib_NSStringHashValue(NSString *NS_RELEASES_ARGUMENT str,
                               bool isASCII) {
  size_t Result =
      isASCII ? str.hash : str.decomposedStringWithCanonicalMapping.hash;

  swift_unknownRelease(str);
  return Result;
}

SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
size_t
swift_stdlib_NSStringHashValuePointer(void *opaque, bool isASCII) {
  NSString *str = (NSString *)opaque;
  return isASCII ? str.hash : str.decomposedStringWithCanonicalMapping.hash;
}


SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
bool swift_stdlib_NSStringHasPrefixNFD(NSString *theString,
                                       NSString *prefix) {
  auto Length = CFStringGetLength((__bridge CFStringRef)theString);
  int Result = CFStringFindWithOptions(
      (__bridge CFStringRef)theString, (__bridge CFStringRef)prefix,
      CFRangeMake(0, Length), kCFCompareAnchored | kCFCompareNonliteral,
      nullptr);
  swift_unknownRelease(theString);
  swift_unknownRelease(prefix);
  return Result;
}

SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
bool swift_stdlib_NSStringHasPrefixNFDPointer(void *theString,
                                              void *prefix) {
  auto Length = CFStringGetLength((__bridge CFStringRef)theString);
  int Result = CFStringFindWithOptions(
      (__bridge CFStringRef)theString, (__bridge CFStringRef)prefix,
      CFRangeMake(0, Length), kCFCompareAnchored | kCFCompareNonliteral,
      nullptr);
  return Result;
}

SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
bool
swift_stdlib_NSStringHasSuffixNFD(NSString *NS_RELEASES_ARGUMENT theString,
                                  NSString *NS_RELEASES_ARGUMENT suffix) {
  auto Length = CFStringGetLength((__bridge CFStringRef)theString);
  int Result = CFStringFindWithOptions(
      (__bridge CFStringRef)theString, (__bridge CFStringRef)suffix,
      CFRangeMake(0, Length),
      kCFCompareAnchored | kCFCompareBackwards | kCFCompareNonliteral, nullptr);
  swift_unknownRelease(theString);
  swift_unknownRelease(suffix);
  return Result;
}

SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
bool swift_stdlib_NSStringHasSuffixNFDPointer(void *theString,
                                              void *suffix) {
  auto Length = CFStringGetLength((__bridge CFStringRef)theString);
  int Result = CFStringFindWithOptions(
      (__bridge CFStringRef)theString, (__bridge CFStringRef)suffix,
      CFRangeMake(0, Length),
      kCFCompareAnchored | kCFCompareBackwards | kCFCompareNonliteral, nullptr);
  return Result;
}

SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
NS_RETURNS_RETAINED NSString *
swift_stdlib_NSStringLowercaseString(NSString *NS_RELEASES_ARGUMENT str) {
  NSString *Result = objc_retain(str.lowercaseString);
  swift_unknownRelease(str);
  return Result;
}

SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
NS_RETURNS_RETAINED NSString *
swift_stdlib_NSStringUppercaseString(NSString *NS_RELEASES_ARGUMENT str) {
  NSString *Result = objc_retain(str.uppercaseString);
  swift_unknownRelease(str);
  return Result;
}

SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
void swift_stdlib_CFSetGetValues(NSSet *NS_RELEASES_ARGUMENT set,
                                            const void **values) {
  CFSetGetValues((__bridge CFSetRef)set, values);
  swift_unknownRelease(set);
}
#endif

// ${'Local Variables'}:
// eval: (read-only-mode 1)
// End:
