<commit_before>//
//  Registration.swift
//  Guise
//
//  Created by <NAME> on 9/3/17.
//  Copyright © 2017 <NAME>. All rights reserved.
//

import Foundation

/**
 The type of a resolution block.
 
 Guise does not register types or instances directly.
 Instead, it registers resolution blocks, which have
 the type given below.
 
 In most cases, the type of `P` is `Void`, i.e., no
 argument at all, e.g.,
 
 ```
 Guise.register{ SomeDependency() as SomeAbstraction }
 ```
 */
public typealias Resolution<P, T> = (P) -> T

/**
 A simple class to hold the resolution block
 and a few other interesting bits.
 */
class Registration {
    /**
     A private serial dispatch queue for cache resolution.
     
     This just ensures that we don't resolve more than once
     due to concurrency when creating a cached value.
     */
    private let cacheQueue: DispatchQueue
    /// Default lifecycle for the dependency
    let cached: Bool
    /// The registered resolution block
    private let resolution: (Any) -> Any
    /// Cached instance, if any
    private var instance: Any?
    /// Metadata, which defaults to an instance of `Void`, i.e., `()`
    let metadata: Any
    
    init<P, T>(metadata: Any, cached: Bool, resolution: @escaping Resolution<P, T>) {
        self.metadata = metadata
        self.cached = cached
        self.resolution = { param in resolution(param as! P) }
        let label = "com.prosumma.Guise.Dependency.[\(String(reflecting: T.self))].\(UUID())"
        self.cacheQueue = DispatchQueue(label: label)
    }
    
    /// - warning: An incompatible `T` will cause an unrecoverable runtime exception.
    func resolve<T>(parameter: Any, cached: Bool?) -> T {
        var result: T
        if cached ?? self.cached {
            if instance == nil {
                cacheQueue.sync {
                    if instance != nil { return }
                    instance = resolution(parameter)
                }
            }
            result = instance! as! T
        } else {
            result = resolution(parameter) as! T
        }
        return result
    }
}<commit_msg>Create cache queue on demand<commit_after>//
//  Registration.swift
//  Guise
//
//  Created by <NAME> on 9/3/17.
//  Copyright © 2017 <NAME>. All rights reserved.
//

import Foundation

/**
 The type of a resolution block.
 
 Guise does not register types or instances directly.
 Instead, it registers resolution blocks, which have
 the type given below.
 
 In most cases, the type of `P` is `Void`, i.e., no
 argument at all, e.g.,
 
 ```
 Guise.register{ SomeDependency() as SomeAbstraction }
 ```
 */
public typealias Resolution<P, T> = (P) -> T

/**
 A simple class to hold the resolution block
 and a few other interesting bits.
 */
class Registration {
    /**
     A private serial dispatch queue for cache resolution.
     
     This just ensures that we don't resolve more than once
     due to concurrency when creating a cached value.
     */
    private var cacheQueue: DispatchQueue?
    /// Default lifecycle for the dependency
    let cached: Bool
    /// The registered resolution block
    private let resolution: (Any) -> Any
    /// Cached instance, if any
    private var instance: Any?
    /// Metadata, which defaults to an instance of `Void`, i.e., `()`
    let metadata: Any
    
    init<P, T>(metadata: Any, cached: Bool, resolution: @escaping Resolution<P, T>) {
        self.metadata = metadata
        self.cached = cached
        self.resolution = { param in resolution(param as! P) }
    }
    
    /// - warning: An incompatible `T` will cause an unrecoverable runtime exception.
    func resolve<T>(parameter: Any, cached: Bool?) -> T {
        var result: T
        if cached ?? self.cached {
            if instance == nil {
                cacheQueue ??= DispatchQueue(label: "com.prosumma.Guise.Dependency.[\(String(reflecting: T.self))].\(UUID())")
                cacheQueue!.sync {
                    if instance != nil { return }
                    instance = resolution(parameter)
                }
            }
            result = instance! as! T
        } else {
            result = resolution(parameter) as! T
        }
        return result
    }
}
{'fraction_non_alphanumeric': 0.1065651760228354, 'fraction_numerical': 0.003805899143672693, 'mean_word_length': 2.1474550898203595, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '480642', 'n_tokens_mistral': 1176, 'n_tokens_neox': 1122, 'n_words': 439}