forked from dotnet/fsharp
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
37 changed files
with
592 additions
and
306 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
//------------------------------------------------------------------------ | ||
// shims for things not yet implemented in Fable | ||
//------------------------------------------------------------------------ | ||
|
||
namespace System.Collections.Concurrent | ||
|
||
open System.Collections.Generic | ||
|
||
// not thread safe, just a ResizeArray // TODO: threaded implementation | ||
type ConcurrentStack<'T>() = | ||
let xs = ResizeArray<'T>() | ||
|
||
member _.Push (item: 'T) = xs.Add(item) | ||
member _.PushRange (items: 'T[]) = xs.AddRange(items) | ||
member _.Clear () = xs.Clear() | ||
member _.ToArray () = xs.ToArray() | ||
|
||
interface IEnumerable<'T> with | ||
member _.GetEnumerator() = | ||
xs.GetEnumerator() | ||
|
||
interface System.Collections.IEnumerable with | ||
member _.GetEnumerator() = | ||
(xs.GetEnumerator() :> System.Collections.IEnumerator) | ||
|
||
// not thread safe, just a Dictionary // TODO: threaded implementation | ||
[<AllowNullLiteral>] | ||
type ConcurrentDictionary<'K, 'V>(comparer: IEqualityComparer<'K>) = | ||
inherit Dictionary<'K, 'V>(comparer) | ||
|
||
new () = | ||
ConcurrentDictionary<'K, 'V>(EqualityComparer.Default) | ||
new (_concurrencyLevel: int, _capacity: int) = | ||
ConcurrentDictionary<'K, 'V>() | ||
new (_concurrencyLevel: int, comparer: IEqualityComparer<'K>) = | ||
ConcurrentDictionary<'K, 'V>(comparer) | ||
new (_concurrencyLevel: int, _capacity: int, comparer: IEqualityComparer<'K>) = | ||
ConcurrentDictionary<'K, 'V>(comparer) | ||
|
||
member x.TryAdd (key: 'K, value: 'V): bool = | ||
if x.ContainsKey(key) | ||
then false | ||
else x.Add(key, value); true | ||
|
||
member x.TryRemove (key: 'K): bool * 'V = | ||
match x.TryGetValue(key) with | ||
| true, v -> (x.Remove(key), v) | ||
| _ as res -> res | ||
|
||
member x.GetOrAdd (key: 'K, value: 'V): 'V = | ||
match x.TryGetValue(key) with | ||
| true, v -> v | ||
| _ -> let v = value in x.Add(key, v); v | ||
|
||
member x.GetOrAdd (key: 'K, valueFactory: System.Func<'K, 'V>): 'V = | ||
match x.TryGetValue(key) with | ||
| true, v -> v | ||
| _ -> let v = valueFactory.Invoke(key) in x.Add(key, v); v | ||
|
||
// member x.GetOrAdd<'Arg> (key: 'K, valueFactory: 'K * 'Arg -> 'V, arg: 'Arg): 'V = | ||
// match x.TryGetValue(key) with | ||
// | true, v -> v | ||
// | _ -> let v = valueFactory(key, arg) in x.Add(key, v); v | ||
|
||
member x.TryUpdate (key: 'K, value: 'V, comparisonValue: 'V): bool = | ||
match x.TryGetValue(key) with | ||
| true, v when Unchecked.equals v comparisonValue -> x[key] <- value; true | ||
| _ -> false | ||
|
||
member x.AddOrUpdate (key: 'K, value: 'V, updateFactory: System.Func<'K, 'V, 'V>): 'V = | ||
match x.TryGetValue(key) with | ||
| true, v -> let v = updateFactory.Invoke(key, v) in x[key] <- v; v | ||
| _ -> let v = value in x.Add(key, v); v | ||
|
||
// member x.AddOrUpdate (key: 'K, valueFactory: 'K -> 'V, updateFactory: 'K * 'V -> 'V): 'V = | ||
// match x.TryGetValue(key) with | ||
// | true, v -> let v = updateFactory(key, v) in x[key] <- v; v | ||
// | _ -> let v = valueFactory(key) in x.Add(key, v); v | ||
|
||
// member x.AddOrUpdate (key: 'K, valueFactory: 'K * 'Arg -> 'V, updateFactory: 'K * 'Arg * 'V -> 'V, arg: 'Arg): 'V = | ||
// match x.TryGetValue(key) with | ||
// | true, v -> let v = updateFactory(key, arg, v) in x[key] <- v; v | ||
// | _ -> let v = valueFactory(key, arg) in x.Add(key, v); v |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
//------------------------------------------------------------------------ | ||
// shims for things not yet implemented in Fable | ||
//------------------------------------------------------------------------ | ||
|
||
namespace System.Collections.Generic | ||
|
||
[<AllowNullLiteral>] | ||
type LinkedListNode<'T>(value: 'T) = | ||
member val Value = value with get, set | ||
member val Previous: LinkedListNode<'T> = null with get, set | ||
member val Next: LinkedListNode<'T> = null with get, set | ||
|
||
type LinkedList<'T>() = | ||
let mutable head: LinkedListNode<'T> = null | ||
let mutable tail: LinkedListNode<'T> = null | ||
|
||
// Get the first node in the list | ||
member _.First = head | ||
|
||
// Get the last node in the list | ||
member _.Last = tail | ||
|
||
// Get the number of nodes in the list | ||
member _.Count = | ||
let rec loop (currentNode: LinkedListNode<'T>) count = | ||
if currentNode = null then count | ||
else loop currentNode.Next (count + 1) | ||
loop head 0 | ||
|
||
// Clear the list | ||
member _.Clear() = | ||
head <- null | ||
tail <- null | ||
|
||
// Add a new node to the end of the list | ||
member _.AddLast(value: 'T) = | ||
let newNode = LinkedListNode(value) | ||
if tail = null then | ||
head <- newNode | ||
tail <- newNode | ||
else | ||
tail.Next <- newNode | ||
newNode.Previous <- tail | ||
tail <- newNode | ||
newNode | ||
|
||
// Add a node to the end of the list | ||
member _.AddLast(node: LinkedListNode<'T>) = | ||
if tail = null then | ||
node.Next <- null | ||
node.Previous <- null | ||
head <- node | ||
tail <- node | ||
else | ||
tail.Next <- node | ||
node.Next <- null | ||
node.Previous <- tail | ||
tail <- node | ||
|
||
// Add a new node to the beginning of the list | ||
member _.AddFirst(value: 'T) = | ||
let newNode = LinkedListNode(value) | ||
if head = null then | ||
head <- newNode | ||
tail <- newNode | ||
else | ||
head.Previous <- newNode | ||
newNode.Next <- head | ||
head <- newNode | ||
newNode | ||
|
||
// Add a node to the beginning of the list | ||
member _.AddFirst(node: LinkedListNode<'T>) = | ||
if head = null then | ||
node.Next <- null | ||
node.Previous <- null | ||
head <- node | ||
tail <- node | ||
else | ||
head.Previous <- node | ||
node.Next <- head | ||
node.Previous <- null | ||
head <- node | ||
|
||
// Remove a node from the list | ||
member _.Remove(node: LinkedListNode<'T>) = | ||
match node.Previous, node.Next with | ||
| null, null -> | ||
head <- null | ||
tail <- null | ||
| null, nextNode -> | ||
nextNode.Previous <- null | ||
head <- nextNode | ||
| prevNode, null -> | ||
prevNode.Next <- null | ||
tail <- prevNode | ||
| prevNode, nextNode -> | ||
prevNode.Next <- nextNode | ||
nextNode.Previous <- prevNode | ||
|
||
// Find a node by value | ||
member _.Find(value: 'T) = | ||
let rec loop (currentNode: LinkedListNode<'T>) = | ||
if currentNode = null then null | ||
elif Unchecked.equals currentNode.Value value then currentNode | ||
else loop currentNode.Next | ||
loop head | ||
|
||
// Implement IEnumerable interface | ||
interface System.Collections.Generic.IEnumerable<'T> with | ||
member _.GetEnumerator() = | ||
let rec loop (currentNode: LinkedListNode<'T>) = | ||
seq { | ||
if currentNode <> null then | ||
yield currentNode.Value | ||
yield! loop currentNode.Next | ||
} | ||
(loop head).GetEnumerator() | ||
|
||
member this.GetEnumerator() : System.Collections.IEnumerator = | ||
(this :> System.Collections.Generic.IEnumerable<'T>).GetEnumerator() :> System.Collections.IEnumerator |
Oops, something went wrong.