123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557 |
- discard """
- output: '''
- 20.0 USD
- true
- true
- true
- true
- true
- f
- 0
- 10
- 10
- 5
- ()
- false
- 10
- true
- true
- true
- true
- p has been called.
- p has been called.
- implicit generic
- generic
- false
- true
- -1
- Meow
- 10 0.0
- 1 2.0
- '''
- joinable: false
- """
- import macros, typetraits, os, posix
- block t5983:
- const currencies = ["USD", "EUR"] # in real code 120 currencies
- type USD = distinct float # in real code 120 types generates using macro
- type EUR = distinct float
- type CurrencyAmount = concept c
- type t = c.type
- const name = c.type.name
- name in currencies
- proc `$`(x: CurrencyAmount): string =
- $float(x) & " " & x.name
- let amount = 20.USD
- echo amount
- block t3414:
- type
- View[T] = concept v
- v.empty is bool
- v.front is T
- popFront v
- proc find(view: View; target: View.T): View =
- result = view
- while not result.empty:
- if view.front == target:
- return
- mixin popFront
- popFront result
- proc popFront[T](s: var seq[T]) = discard
- proc empty[T](s: seq[T]): bool = false
- var s1 = @[1, 2, 3]
- let s2 = s1.find(10)
- block t1128:
- type
- TFooContainer[T] = object
- TContainer[T] = concept var c
- foo(c, T)
- proc foo[T](c: var TFooContainer[T], val: T) =
- discard
- proc bar(c: var TContainer) =
- discard
- var fooContainer: TFooContainer[int]
- echo fooContainer is TFooContainer # true.
- echo fooContainer is TFooContainer[int] # true.
- fooContainer.bar()
- block t5642:
- type DataTable = concept x
- x is object
- for f in fields(x):
- f is seq
- type Students = object
- id : seq[int]
- name : seq[string]
- age: seq[int]
- proc nrow(dt: DataTable) : Natural =
- var totalLen = 0
- for f in fields(dt):
- totalLen += f.len
- return totalLen
- let
- stud = Students(id: @[1,2,3], name: @["Vas", "Pas", "NafNaf"], age: @[10,16,32])
- doAssert nrow(stud) == 9
- import t5888lib/ca, t5888lib/opt
- block t5888:
- type LocalCA = ca.CA
- proc f(c: CA) =
- echo "f"
- echo c.x
- var o = new(Opt)
- echo o is CA
- echo o is LocalCA
- echo o is ca.CA
- o.f()
- import json
- block t5968:
- type
- Enumerable[T] = concept e
- for it in e:
- it is T
- proc cmap[T, G](e: Enumerable[T], fn: proc(t: T): G): seq[G] =
- result = @[]
- for it in e: result.add(fn(it))
- var x = %["hello", "world"]
- var z = x.cmap(proc(it: JsonNode): string = it.getStr & "!")
- assert z == @["hello!", "world!"]
- import sugar
- block t6462:
- type
- FilterMixin[T] = ref object
- test: (T) -> bool
- trans: (T) -> T
- SeqGen[T] = ref object
- fil: FilterMixin[T]
- WithFilter[T] = concept a
- a.fil is FilterMixin[T]
- proc test[T](a: WithFilter[T]): (T) -> bool =
- a.fil.test
- var s = SeqGen[int](fil: FilterMixin[int](test: nil, trans: nil))
- doAssert s.test() == nil
- block t6770:
- type GA = concept c
- c.a is int
- type A = object
- a: int
- type AA = object
- case exists: bool
- of true:
- a: int
- else:
- discard
- proc print(inp: GA) =
- echo inp.a
- let failing = AA(exists: true, a: 10)
- let working = A(a:10)
- print(working)
- print(failing)
- block t7952:
- type
- HasLen = concept iter
- len(iter) is int
- proc echoLen(x: HasLen) =
- echo len(x)
- echoLen([1, 2, 3, 4, 5])
- block t8280:
- type
- Iterable[T] = concept x
- for elem in x:
- elem is T
- proc max[A](iter: Iterable[A]): A =
- discard
- type
- MyType = object
- echo max(@[MyType()])
- import math
- block t3452:
- type
- Node = concept n
- `==`(n, n) is bool
- Graph1 = concept g
- type N = Node
- distance(g, N, N) is float
- Graph2 = concept g
- distance(g, Node, Node) is float
- Graph3 = concept g
- var x: Node
- distance(g, x, x) is float
- XY = tuple[x, y: int]
- MyGraph = object
- points: seq[XY]
- static:
- assert XY is Node
- proc distance( g: MyGraph, a, b: XY): float =
- sqrt( pow(float(a.x - b.x), 2) + pow(float(a.y - b.y), 2) )
- static:
- assert MyGraph is Graph1
- assert MyGraph is Graph2
- assert MyGraph is Graph3
- block t6691:
- type
- ConceptA = concept c
- ConceptB = concept c
- c.myProc(ConceptA)
- Obj = object
- proc myProc(obj: Obj, x: ConceptA) = discard
- echo Obj is ConceptB
- block t6782:
- type
- Reader = concept c
- c.read(openArray[byte], int, int) is int
- Rdr = concept c
- c.rd(openArray[byte], int, int) is int
- type TestFile = object
- proc read(r: TestFile, dest: openArray[byte], offset: int, limit: int): int =
- result = 0
- proc rd(r: TestFile, dest: openArray[byte], offset: int, limit: int): int =
- result = 0
- doAssert TestFile is Reader
- doAssert TestFile is Rdr
- block t7114:
- type
- MyConcept = concept x
- x.close() # error, doesn't work
- MyConceptImplementer = object
- proc close(self: MyConceptImplementer) = discard
- proc takeConcept(window: MyConcept) =
- discard
- takeConcept(MyConceptImplementer())
- block t7510:
- type
- A[T] = concept a
- a.x is T
- B[T] = object
- x: T
- proc getx(v: A): v.T = v.x
- var v = B[int32](x: 10)
- echo v.getx
- block misc_issues:
- # https://github.com/nim-lang/Nim/issues/1147
- type TTest = object
- vals: seq[int]
- proc add(self: var TTest, val: int) =
- self.vals.add(val)
- type CAddable = concept x
- x[].add(int)
- echo((ref TTest) is CAddable) # true
- # https://github.com/nim-lang/Nim/issues/1570
- type ConcretePointOfFloat = object
- x, y: float
- type ConcretePoint[Value] = object
- x, y: Value
- type AbstractPointOfFloat = concept p
- p.x is float and p.y is float
- let p1 = ConcretePointOfFloat(x: 0, y: 0)
- let p2 = ConcretePoint[float](x: 0, y: 0)
- echo p1 is AbstractPointOfFloat # true
- echo p2 is AbstractPointOfFloat # true
- echo p2.x is float and p2.y is float # true
- # https://github.com/nim-lang/Nim/issues/2018
- type ProtocolFollower = concept c
- true # not a particularly involved protocol
- type ImplementorA = object
- type ImplementorB = object
- proc p[A: ProtocolFollower, B: ProtocolFollower](a: A, b: B) =
- echo "p has been called."
- p(ImplementorA(), ImplementorA())
- p(ImplementorA(), ImplementorB())
- # https://github.com/nim-lang/Nim/issues/2423
- proc put[T](c: seq[T], x: T) = echo "generic"
- proc put(c: seq) = echo "implicit generic"
- type
- Container[T] = concept c
- put(c)
- put(c, T)
- proc c1(x: Container) = echo "implicit generic"
- c1(@[1])
- proc c2[T](x: Container[T]) = echo "generic"
- c2(@[1])
- # https://github.com/nim-lang/Nim/issues/2882
- type
- Paper = object
- name: string
- Bendable = concept x
- bend(x is Bendable)
- proc bend(p: Paper): Paper = Paper(name: "bent-" & p.name)
- var paper = Paper(name: "red")
- echo paper is Bendable
- type
- A = concept self
- size(self) is int
- B = object
- proc size(self: B): int =
- return -1
- proc size(self: A): int =
- return 0
- let b = B()
- echo b is A
- echo b.size()
- # https://github.com/nim-lang/Nim/issues/7125
- type
- Thing = concept x
- x.hello is string
- Cat = object
- proc hello(d: Cat): string = "Meow"
- proc sayHello(c: Thing) = echo(c.hello)
- # used to be 'var a: Thing = Cat()' but that's not valid Nim code
- # anyway and will be an error soon.
- var a: Cat = Cat()
- a.sayHello()
- # bug #16897
- type
- Fp[N: static int, T] = object
- big: array[N, T]
- type
- QuadraticExt* = concept x
- ## Quadratic Extension concept (like complex)
- type BaseField = auto
- x.c0 is BaseField
- x.c1 is BaseField
- var address = pointer(nil)
- proc prod(r: var QuadraticExt, b: QuadraticExt) =
- if address == nil:
- address = addr b
- prod(r, b)
- else:
- assert address == addr b
- type
- Fp2[N: static int, T] {.byref.} = object
- c0, c1: Fp[N, T]
- # This should be passed by reference,
- # but concepts do not respect the 24 bytes rule
- # or `byref` pragma.
- var r, b: Fp2[6, uint64]
- prod(r, b)
- block: # bug #21263
- type
- DateDayFraction = concept # no T, an atom
- proc date(a: Self): int
- proc fraction(b: Self): float
- Date = distinct int
- DateDayFractionImpl = object
- date : int
- fraction : float
- proc date(a: Date): int = a.int
- proc fraction(a:Date): float = 0.0
- proc date(a: DateDayFractionImpl): int = a.date
- proc fraction(b: DateDayFractionImpl): float = b.fraction
- proc print(a: DateDayFraction) =
- echo a.date, " ", a.fraction
- print(10.Date) # ok
- print(DateDayFractionImpl(date: 1, fraction: 2)) # error
- import sets
- import deques
- type AnyTree[V] = concept t, type T
- for v in t.leaves(V):
- v is V
- type BreadthOrder[V] = ref object
- frontier: Deque[V]
- visited: HashSet[V]
- proc expand[V, T](order: ref BreadthOrder[T], tree: AnyTree[V], node: V, transform: (V) -> (T)) =
- for leaf in tree.leaves(node):
- if not order.visited.containsOrIncl(transform(leaf)):
- order.frontier.addLast(transform(leaf))
- proc hasNext[V](order: ref BreadthOrder[V]): bool =
- order.frontier.len > 0
- proc init[V](_: typedesc[BreadthOrder]): ref BreadthOrder[V] =
- result.new()
- result[] = BreadthOrder[V](frontier: initDeque[V](), visited: initHashSet[V]())
- proc popNext[V](order: ref BreadthOrder[V]): V =
- order.frontier.popFirst()
- type LevelNode[V] = tuple
- depth: uint
- node: V
- proc depthOf*[V](orderType: typedesc[BreadthOrder], tree: AnyTree[V], root, goal: V): uint =
- if root == goal:
- return 0
- var order = init[LevelNode[V]](orderType)
- order.expand(tree, root, (leaf) => (1.uint, leaf))
- while order.hasNext():
- let depthNode: LevelNode[V] = order.popNext()
- if depthNode.node == goal:
- return depthNode.depth
- order.expand(tree, depthNode.node, (leaf) => (depthNode.depth + 1, leaf))
- type CappedStringTree = ref object
- symbols: string
- cap: Natural
- iterator leaves*(t: CappedStringTree, s: string): string =
- if s.len < t.cap:
- for c in t.symbols:
- yield s & c
- block: # bug #12852
- var tree = CappedStringTree(symbols: "^v><", cap: 5)
- doAssert BreadthOrder.depthOf(tree, "", ">>>") == 3
- block: #bug #22723
- type
- Node = concept n, type T
- for i in n.children:
- i is T
- n.parent is T
- Nd = ref object
- parent: Nd
- children: seq[Nd]
- proc addChild(parent, child: Node) =
- parent.children.add(child)
- child.parent = parent
- proc foo =
- var
- a = Nd()
- b = Nd()
- a.addChild(b)
- doAssert a.children.len == 1
- foo()
|