|
15 | 15 | import std/private/since
|
16 | 16 | export system.`$` # for backward compatibility
|
17 | 17 |
|
18 |
| -proc name*(t: typedesc): string {.magic: "TypeTrait".} |
| 18 | +proc name*(t: typedesc): string {.magic: "TypeTrait".} = |
19 | 19 | ## Returns the name of the given type.
|
20 | 20 | ##
|
21 |
| - ## Alias for system.`$`(t) since Nim v0.20. |
| 21 | + ## Alias for `system.\`$\`(t) <dollars.html#$,typedesc>`_ since Nim v0.20. |
| 22 | + runnableExamples: |
| 23 | + doAssert name(int) == "int" |
| 24 | + doAssert name(seq[string]) == "seq[string]" |
22 | 25 |
|
23 | 26 | proc arity*(t: typedesc): int {.magic: "TypeTrait".} =
|
24 | 27 | ## Returns the arity of the given type. This is the number of "type"
|
25 |
| - ## components or the number of generic parameters a given type ``t`` has. |
| 28 | + ## components or the number of generic parameters a given type `t` has. |
26 | 29 | runnableExamples:
|
27 |
| - assert arity(seq[string]) == 1 |
28 |
| - assert arity(array[3, int]) == 2 |
29 |
| - assert arity((int, int, float, string)) == 4 |
| 30 | + doAssert arity(int) == 0 |
| 31 | + doAssert arity(seq[string]) == 1 |
| 32 | + doAssert arity(array[3, int]) == 2 |
| 33 | + doAssert arity((int, int, float, string)) == 4 |
30 | 34 |
|
31 | 35 | proc genericHead*(t: typedesc): typedesc {.magic: "TypeTrait".} =
|
32 | 36 | ## Accepts an instantiated generic type and returns its
|
33 | 37 | ## uninstantiated form.
|
34 | 38 | ## A compile-time error will be produced if the supplied type
|
35 | 39 | ## is not generic.
|
36 | 40 | ##
|
37 |
| - ## See also: |
38 |
| - ## * `stripGenericParams <#stripGenericParams,typedesc>`_ |
| 41 | + ## **See also:** |
| 42 | + ## * `stripGenericParams proc <#stripGenericParams,typedesc>`_ |
39 | 43 | runnableExamples:
|
40 | 44 | type
|
41 | 45 | Foo[T] = object
|
42 | 46 | FooInst = Foo[int]
|
43 | 47 | Foo2 = genericHead(FooInst)
|
| 48 | + |
44 | 49 | doAssert Foo2 is Foo and Foo is Foo2
|
45 | 50 | doAssert genericHead(Foo[seq[string]]) is Foo
|
46 | 51 | doAssert not compiles(genericHead(int))
|
47 | 52 |
|
48 | 53 | type Generic = concept f
|
49 | 54 | type _ = genericHead(typeof(f))
|
| 55 | + |
50 | 56 | proc bar(a: Generic): typeof(a) = a
|
| 57 | + |
51 | 58 | doAssert bar(Foo[string].default) == Foo[string]()
|
52 | 59 | doAssert not compiles bar(string.default)
|
53 | 60 |
|
54 | 61 | when false: # these don't work yet
|
55 | 62 | doAssert genericHead(Foo[int])[float] is Foo[float]
|
56 | 63 | doAssert seq[int].genericHead is seq
|
57 | 64 |
|
58 |
| -proc stripGenericParams*(t: typedesc): typedesc {.magic: "TypeTrait".} |
| 65 | +proc stripGenericParams*(t: typedesc): typedesc {.magic: "TypeTrait".} = |
59 | 66 | ## This trait is similar to `genericHead <#genericHead,typedesc>`_, but
|
60 |
| - ## instead of producing error for non-generic types, it will just return |
| 67 | + ## instead of producing an error for non-generic types, it will just return |
61 | 68 | ## them unmodified.
|
| 69 | + runnableExamples: |
| 70 | + type Foo[T] = object |
| 71 | + |
| 72 | + doAssert stripGenericParams(Foo[string]) is Foo |
| 73 | + doAssert stripGenericParams(int) is int |
62 | 74 |
|
63 | 75 | proc supportsCopyMem*(t: typedesc): bool {.magic: "TypeTrait".}
|
64 |
| - ## This trait returns true if the type ``t`` is safe to use for |
| 76 | + ## This trait returns true if the type `t` is safe to use for |
65 | 77 | ## `copyMem`:idx:.
|
66 | 78 | ##
|
67 | 79 | ## Other languages name a type like these `blob`:idx:.
|
68 | 80 |
|
69 |
| -proc isNamedTuple*(T: typedesc): bool {.magic: "TypeTrait".} |
70 |
| - ## Return true for named tuples, false for any other type. |
| 81 | +proc isNamedTuple*(T: typedesc): bool {.magic: "TypeTrait".} = |
| 82 | + ## Returns true for named tuples, false for any other type. |
| 83 | + runnableExamples: |
| 84 | + doAssert not isNamedTuple(int) |
| 85 | + doAssert not isNamedTuple((string, int)) |
| 86 | + doAssert isNamedTuple(tuple[name: string, age: int]) |
| 87 | + |
| 88 | +proc distinctBase*(T: typedesc): typedesc {.magic: "TypeTrait".} = |
| 89 | + ## Returns the base type for distinct types. This works only |
| 90 | + ## for distinct types and produces a compile time error otherwise. |
| 91 | + ## |
| 92 | + ## **See also:** |
| 93 | + ## * `distinctBase template <#distinctBase.t,T>`_ |
| 94 | + runnableExamples: |
| 95 | + type MyInt = distinct int |
71 | 96 |
|
72 |
| -proc distinctBase*(T: typedesc): typedesc {.magic: "TypeTrait".} |
73 |
| - ## Returns base type for distinct types, works only for distinct types. |
74 |
| - ## compile time error otherwise |
| 97 | + doAssert distinctBase(MyInt) is int |
| 98 | + doAssert not compiles(distinctBase(int)) |
75 | 99 |
|
76 | 100 | since (1, 1):
|
77 | 101 | template distinctBase*[T](a: T): untyped =
|
78 |
| - ## overload for values |
| 102 | + ## Overload of `distinctBase <#distinctBase,typedesc>`_ for values. |
79 | 103 | runnableExamples:
|
80 | 104 | type MyInt = distinct int
|
| 105 | + |
81 | 106 | doAssert 12.MyInt.distinctBase == 12
|
| 107 | + |
82 | 108 | distinctBase(type(a))(a)
|
83 | 109 |
|
84 |
| - proc tupleLen*(T: typedesc[tuple]): int {.magic: "TypeTrait".} |
85 |
| - ## Return number of elements of `T` |
| 110 | + proc tupleLen*(T: typedesc[tuple]): int {.magic: "TypeTrait".} = |
| 111 | + ## Returns the number of elements of the tuple type `T`. |
| 112 | + ## |
| 113 | + ## **See also:** |
| 114 | + ## * `tupleLen template <#tupleLen.t>`_ |
| 115 | + runnableExamples: |
| 116 | + doAssert tupleLen((int, int, float, string)) == 4 |
| 117 | + doAssert tupleLen(tuple[name: string, age: int]) == 2 |
86 | 118 |
|
87 | 119 | template tupleLen*(t: tuple): int =
|
88 |
| - ## Return number of elements of `t` |
| 120 | + ## Returns the number of elements of the tuple `t`. |
| 121 | + ## |
| 122 | + ## **See also:** |
| 123 | + ## * `tupleLen proc <#tupleLen,typedesc>`_ |
| 124 | + runnableExamples: |
| 125 | + doAssert tupleLen((1, 2)) == 2 |
| 126 | + |
89 | 127 | tupleLen(type(t))
|
90 | 128 |
|
91 | 129 | template get*(T: typedesc[tuple], i: static int): untyped =
|
92 |
| - ## Return `i`\th element of `T` |
| 130 | + ## Returns the `i`-th element of `T`. |
93 | 131 | # Note: `[]` currently gives: `Error: no generic parameters allowed for ...`
|
| 132 | + runnableExamples: |
| 133 | + doAssert get((int, int, float, string), 2) is float |
| 134 | + |
94 | 135 | type(default(T)[i])
|
95 | 136 |
|
96 | 137 | type StaticParam*[value: static type] = object
|
97 |
| - ## used to wrap a static value in `genericParams` |
| 138 | + ## Used to wrap a static value in `genericParams <#genericParams.t,typedesc>`_. |
98 | 139 |
|
99 | 140 | since (1, 3, 5):
|
100 | 141 | template elementType*(a: untyped): typedesc =
|
101 |
| - ## return element type of `a`, which can be any iterable (over which you |
102 |
| - ## can iterate) |
| 142 | + ## Returns the element type of `a`, which can be any iterable (over which you |
| 143 | + ## can iterate). |
103 | 144 | runnableExamples:
|
104 | 145 | iterator myiter(n: int): auto =
|
105 |
| - for i in 0..<n: yield i |
| 146 | + for i in 0 ..< n: |
| 147 | + yield i |
| 148 | + |
106 | 149 | doAssert elementType(@[1,2]) is int
|
107 | 150 | doAssert elementType("asdf") is char
|
108 | 151 | doAssert elementType(myiter(3)) is int
|
| 152 | + |
109 | 153 | typeof(block: (for ai in a: ai))
|
110 | 154 |
|
111 | 155 | import std/macros
|
112 | 156 |
|
113 | 157 | macro enumLen*(T: typedesc[enum]): int =
|
114 | 158 | ## Returns the number of items in the enum `T`.
|
115 |
| - |
116 | 159 | runnableExamples:
|
117 |
| - type Foo = enum fooItem1 fooItem2 |
| 160 | + type Foo = enum |
| 161 | + fooItem1 |
| 162 | + fooItem2 |
| 163 | + |
118 | 164 | doAssert Foo.enumLen == 2
|
119 | 165 |
|
120 | 166 | let bracketExpr = getType(T)
|
@@ -179,19 +225,23 @@ macro genericParamsImpl(T: typedesc): untyped =
|
179 | 225 |
|
180 | 226 | since (1, 1):
|
181 | 227 | template genericParams*(T: typedesc): untyped =
|
182 |
| - ## return tuple of generic params for generic `T` |
| 228 | + ## Returns the tuple of generic parameters for the generic type `T`. |
| 229 | + ## |
| 230 | + ## **Note:** For the builtin array type, the index generic parameter will |
| 231 | + ## **always** become a range type after it's bound to a variable. |
183 | 232 | runnableExamples:
|
184 | 233 | type Foo[T1, T2] = object
|
| 234 | + |
185 | 235 | doAssert genericParams(Foo[float, string]) is (float, string)
|
| 236 | + |
186 | 237 | type Bar[N: static float, T] = object
|
| 238 | + |
187 | 239 | doAssert genericParams(Bar[1.0, string]) is (StaticParam[1.0], string)
|
188 | 240 | doAssert genericParams(Bar[1.0, string]).get(0).value == 1.0
|
189 | 241 | doAssert genericParams(seq[Bar[2.0, string]]).get(0) is Bar[2.0, string]
|
190 | 242 | var s: seq[Bar[3.0, string]]
|
191 | 243 | doAssert genericParams(typeof(s)) is (Bar[3.0, string],)
|
192 | 244 |
|
193 |
| - # NOTE: For the builtin array type, the index generic param will |
194 |
| - # **always** become a range type after it's bound to a variable. |
195 | 245 | doAssert genericParams(array[10, int]) is (StaticParam[10], int)
|
196 | 246 | var a: array[10, int]
|
197 | 247 | doAssert genericParams(typeof(a)) is (range[0..9], int)
|
|
0 commit comments