From 37ae1b2c644ee971951bc3e264273b24e2d0974a Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Thu, 27 Feb 2020 21:16:39 -0800 Subject: [PATCH 1/8] add isDefault; more general than isNil, isEmpty etc --- changelog.md | 1 + lib/system.nim | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/changelog.md b/changelog.md index f106ac2c23c07..f4768c34a5ef7 100644 --- a/changelog.md +++ b/changelog.md @@ -81,6 +81,7 @@ ``` +- Added `system.isDefault(a)` to tell whether `a` is equal to its default value ## Library changes diff --git a/lib/system.nim b/lib/system.nim index 51ff3af400341..8c27b84549cb6 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -909,6 +909,34 @@ else: else: proc reset*[T](obj: var T) {.magic: "Reset", noSideEffect.} +when defined(nimHasDefault): + proc isDefault*[T: not seq](a: T): bool {.inline.} = + ## returns whether `a` is equal to its default value + runnableExamples: + doAssert "".isDefault + doAssert not "a".isDefault + doAssert (-0.0).isDefault + doAssert not @[0].isDefault + doAssert [0].isDefault # whereas [0].len != 0 + + type Kind = enum kUnknown, kRed, kGreen + doAssert kUnknown.isDefault + + type Foo1 = ref object + type Foo2 = object + doAssert not Foo1().isDefault + doAssert Foo2().isDefault + + a == default(T) + +template isDefault*(a: string): bool = + ## overloaded for efficiency + a.len == 0 + +template isDefault*(a: seq): bool = + ## overloaded for efficiency + a.len == 0 + proc setLen*[T](s: var seq[T], newlen: Natural) {. magic: "SetLengthSeq", noSideEffect.} ## Sets the length of seq `s` to `newlen`. ``T`` may be any sequence type. From 02a590b5fbad71cedbce5358e280159e56171fcf Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Thu, 27 Feb 2020 23:02:52 -0800 Subject: [PATCH 2/8] fixup --- lib/system.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/system.nim b/lib/system.nim index 8c27b84549cb6..12065a019e4a1 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -910,7 +910,7 @@ else: proc reset*[T](obj: var T) {.magic: "Reset", noSideEffect.} when defined(nimHasDefault): - proc isDefault*[T: not seq](a: T): bool {.inline.} = + proc isDefault*[T](a: T): bool {.inline.} = ## returns whether `a` is equal to its default value runnableExamples: doAssert "".isDefault @@ -933,7 +933,7 @@ template isDefault*(a: string): bool = ## overloaded for efficiency a.len == 0 -template isDefault*(a: seq): bool = +template isDefault*[T](a: seq[T]): bool = ## overloaded for efficiency a.len == 0 From 9a191311f646cdb526da45133bffddbc90d50337 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Thu, 27 Feb 2020 23:39:14 -0800 Subject: [PATCH 3/8] fixup --- lib/system.nim | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/lib/system.nim b/lib/system.nim index 12065a019e4a1..2c342ee0210e3 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -909,18 +909,21 @@ else: else: proc reset*[T](obj: var T) {.magic: "Reset", noSideEffect.} -when defined(nimHasDefault): +when (NimMajor, NimMinor) >= (1, 1): proc isDefault*[T](a: T): bool {.inline.} = ## returns whether `a` is equal to its default value runnableExamples: doAssert "".isDefault doAssert not "a".isDefault - doAssert (-0.0).isDefault doAssert not @[0].isDefault + + ## semantic differences with something like isEmpty: doAssert [0].isDefault # whereas [0].len != 0 + doAssert not "".cstring.isDefault # whereas "".cstring.len == 0 type Kind = enum kUnknown, kRed, kGreen doAssert kUnknown.isDefault + doAssert (-0.0).isDefault type Foo1 = ref object type Foo2 = object @@ -929,13 +932,13 @@ when defined(nimHasDefault): a == default(T) -template isDefault*(a: string): bool = - ## overloaded for efficiency - a.len == 0 + template isDefault*(a: string): bool = + ## overloaded for efficiency + a.len == 0 -template isDefault*[T](a: seq[T]): bool = - ## overloaded for efficiency - a.len == 0 + template isDefault*[T](a: seq[T]): bool = + ## overloaded for efficiency + a.len == 0 proc setLen*[T](s: var seq[T], newlen: Natural) {. magic: "SetLengthSeq", noSideEffect.} From 167c944fe8a6619a5e37013ad2f3a8daf46dd135 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Thu, 27 Feb 2020 23:53:13 -0800 Subject: [PATCH 4/8] use since --- lib/system.nim | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/lib/system.nim b/lib/system.nim index 2c342ee0210e3..44d7e940e31df 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -479,6 +479,24 @@ let nimvm* {.magic: "Nimvm", compileTime.}: bool = false include "system/arithmetics" include "system/comparisons" +const + NimMajor* {.intdefine.}: int = 1 + ## is the major number of Nim's version. + + NimMinor* {.intdefine.}: int = 1 + ## is the minor number of Nim's version. + + NimPatch* {.intdefine.}: int = 1 + ## is the patch number of Nim's version. + +template since2(version, body: untyped) {.dirty.} = + ## poor-man's version of inclrtl.since without `>=` defined + const + v0 = version[0] + v1 = version[1] + when NimMajor > v0 or NimMajor == v0 and NimMinor >= v1: + body + const appType* {.magic: "AppType"}: string = "" ## A string that describes the application type. Possible values: @@ -909,7 +927,7 @@ else: else: proc reset*[T](obj: var T) {.magic: "Reset", noSideEffect.} -when (NimMajor, NimMinor) >= (1, 1): +since2 (1, 1): proc isDefault*[T](a: T): bool {.inline.} = ## returns whether `a` is equal to its default value runnableExamples: @@ -2080,15 +2098,6 @@ import system/dollars export dollars const - NimMajor* {.intdefine.}: int = 1 - ## is the major number of Nim's version. - - NimMinor* {.intdefine.}: int = 1 - ## is the minor number of Nim's version. - - NimPatch* {.intdefine.}: int = 1 - ## is the patch number of Nim's version. - NimVersion*: string = $NimMajor & "." & $NimMinor & "." & $NimPatch ## is the version of Nim as a string. From 2840e0615ecda236f60dfcd26278f1eef4cb3ae7 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Fri, 28 Feb 2020 00:27:48 -0800 Subject: [PATCH 5/8] fix test --- tests/errmsgs/twrong_at_operator.nim | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/errmsgs/twrong_at_operator.nim b/tests/errmsgs/twrong_at_operator.nim index ebf6d966b8e2d..9933b0f39aa87 100644 --- a/tests/errmsgs/twrong_at_operator.nim +++ b/tests/errmsgs/twrong_at_operator.nim @@ -4,14 +4,14 @@ line: 22 nimout: ''' twrong_at_operator.nim(22, 30) Error: type mismatch: got but expected one of: -proc `@`[IDX, T](a: sink array[IDX, T]): seq[T] - first type mismatch at position: 1 - required type for a: sink array[IDX, T] - but expression '[int]' is of type: array[0..0, type int] proc `@`[T](a: openArray[T]): seq[T] first type mismatch at position: 1 required type for a: openArray[T] but expression '[int]' is of type: array[0..0, type int] +proc `@`[IDX, T](a: sink array[IDX, T]): seq[T] + first type mismatch at position: 1 + required type for a: sink array[IDX, T] + but expression '[int]' is of type: array[0..0, type int] expression: @[int] ''' From df6104666d32e298644bb1787bc28e00c7471c2b Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Fri, 28 Feb 2020 01:06:33 -0800 Subject: [PATCH 6/8] add notDefault --- lib/system.nim | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/system.nim b/lib/system.nim index 44d7e940e31df..69d1d4f036b52 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -946,6 +946,7 @@ since2 (1, 1): type Foo1 = ref object type Foo2 = object doAssert not Foo1().isDefault + doAssert Foo1().notDefault doAssert Foo2().isDefault a == default(T) @@ -958,6 +959,10 @@ since2 (1, 1): ## overloaded for efficiency a.len == 0 + template notDefault*(a): untyped = + ## negation of `isDefault` + not isDefault(a) + proc setLen*[T](s: var seq[T], newlen: Natural) {. magic: "SetLengthSeq", noSideEffect.} ## Sets the length of seq `s` to `newlen`. ``T`` may be any sequence type. From db34143c994266447fd742953aea2f7b10f8e847 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Fri, 28 Feb 2020 01:20:43 -0800 Subject: [PATCH 7/8] use a template instead for isDefault --- lib/system.nim | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/system.nim b/lib/system.nim index 69d1d4f036b52..fafd40adb2ec9 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -928,7 +928,7 @@ else: proc reset*[T](obj: var T) {.magic: "Reset", noSideEffect.} since2 (1, 1): - proc isDefault*[T](a: T): bool {.inline.} = + template isDefault*[T](a: T): bool = ## returns whether `a` is equal to its default value runnableExamples: doAssert "".isDefault @@ -949,7 +949,8 @@ since2 (1, 1): doAssert Foo1().notDefault doAssert Foo2().isDefault - a == default(T) + # BUG: default(T) would not work but should + a == default(type(a)) template isDefault*(a: string): bool = ## overloaded for efficiency From 5c0f0dbe61c9e56d28a1e590d9de35df94cef194 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Fri, 28 Feb 2020 01:44:36 -0800 Subject: [PATCH 8/8] fixup --- lib/system.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/system.nim b/lib/system.nim index fafd40adb2ec9..d7d6bfc190401 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -949,7 +949,7 @@ since2 (1, 1): doAssert Foo1().notDefault doAssert Foo2().isDefault - # BUG: default(T) would not work but should + # pending https://github.com/nim-lang/Nim/issues/13527, use `default(T)` a == default(type(a)) template isDefault*(a: string): bool =