-
Notifications
You must be signed in to change notification settings - Fork 3
/
Lazy.swift
40 lines (36 loc) · 1.25 KB
/
Lazy.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import Foundation
import os
/// A wrapper class that allows for a dependency to be initialized lazily.
///
/// When the wrapped type is initialized upon invoking the ``get()`` function for the first time,
/// the initialized value will be cached and re-used across subsequent invocations of ``get()``.
///
/// It isn't necessary to declare a provider of type `Lazy<T>`. Any provider of type `T` can be used
/// to satisfy dependencies of both type `T` and `Lazy<T>`.
///
/// > Note: Lazy is thread-safe.
///
/// - Parameters:
/// - initializer: A closure that can be invoked to initialize an instance of `T`
public final class Lazy<T> {
private enum State {
case uninitialized(() -> T)
case initialized(T)
}
private let lock: OSAllocatedUnfairLock<State>
public init(_ initializer: @escaping () -> T) {
self.lock = OSAllocatedUnfairLock(initialState: .uninitialized(initializer))
}
public func get() -> T {
lock.withLock { state in
switch state {
case let .uninitialized(initializer):
let value = initializer()
state = .initialized(value)
return value
case let .initialized(value):
return value
}
}
}
}