Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds toSet to create sets from iterables #16276

Merged
merged 15 commits into from
Dec 14, 2020
Merged
32 changes: 32 additions & 0 deletions lib/std/setutils.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#
#
# The Nim Compiler
# (c) Copyright 2020 Nim Contributors
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#

## This module adds functionality to the builtin set
timotheecour marked this conversation as resolved.
Show resolved Hide resolved
beef331 marked this conversation as resolved.
Show resolved Hide resolved
## See also std/packedsets, set/sets
beef331 marked this conversation as resolved.
Show resolved Hide resolved

import typetraits

type SetElement* = char|byte|bool|int16|uint16|enum|uint8|int8
timotheecour marked this conversation as resolved.
Show resolved Hide resolved
## The allowed types of a builtin set.
timotheecour marked this conversation as resolved.
Show resolved Hide resolved

template toSet*(iter: untyped): untyped =
## Return a builtin set from the elements of iterable `iter`
beef331 marked this conversation as resolved.
Show resolved Hide resolved
runnableExamples:
timotheecour marked this conversation as resolved.
Show resolved Hide resolved
assert "helloWorld".toSet == {'W', 'd', 'e', 'h', 'l', 'o', 'r'}
assert toSet([10u16,20,30]) == {10u16, 20, 30}
assert [30u8,100,10].toSet == {10u8, 30, 100}
assert toSet(@[1321i16,321, 90]) == {90i16, 321, 1321}
beef331 marked this conversation as resolved.
Show resolved Hide resolved
assert toSet([false]) == {false}
assert toSet(0u8..10u8) == {0u8..10u8}
type E = elementType(iter)
static: doAssert E is SetElement, "`iter` does not yield a `SetElement`"
timotheecour marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually, why do we even need the static: doAssert E is SetElement ?
you'll still get an error when attempting var result: set[E] if say, E is int64.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well the main reason is to give a slightly more informative error instead of just set is to large

Copy link
Member

@timotheecour timotheecour Dec 7, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

then we should fix the errmsg in the compiler, where it belongs (which would benefit other code):

nim> var z: set[int]
Error: set is too large

=>

Error: set is too large, got `int` but expected ...

var result: set[E]
for x in iter:
result.incl(x)
timotheecour marked this conversation as resolved.
Show resolved Hide resolved
result
8 changes: 8 additions & 0 deletions tests/stdlib/tsetutils.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
discard """
targets: "c js"
"""
import std/setutils
timotheecour marked this conversation as resolved.
Show resolved Hide resolved

doAssert "abcbb".toSet == {'a','b','c'}
doAssert toSet([10u8,12,13]) == {10u8, 12, 13}
doAssert toSet(0u16..30) == {0u16..30}
timotheecour marked this conversation as resolved.
Show resolved Hide resolved