<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">In this case, I have a standard NS_ENUM with a series of cases. I require to create an NSArray by enumerating through the cases and adding an object per case.</div><div class=""><br class=""></div><div class="">To do so, I either assume what the last case is in the enum and perform a for loop, or I add a final item in the for loop e.g. “EGSectionEnum_Count”, and then enumerate to it.</div><div class=""><br class=""></div><div class="">This is fragile as the moment anyone adds a case beyond the final item, the code becomes incorrect. If I add the EGSectionEnum_Count item, I am exposing an invalid value. Also, it assumes that the enum NSInteger values are continuous increasing by +1. Where someone specifically defines a value for the item, the entire for loop enumerating through fails.</div><div class=""><br class=""></div><div class="">By allowing direct enumeration by case, we avoid assuming values for each item and therefore code fragility, we avoid exposing a count of the items as a separate enum value which should not exist, and we avoid the reliance on Integer based enums, as these previous methods would not work on Swift’s string- and other- type based enums.</div><div class=""><br class=""></div><br class=""><div><blockquote type="cite" class=""><div class="">On 18 Jan 2016, at 1:01 PM, Jacob Bandes-Storch <<a href="mailto:jtbandes@gmail.com" class="">jtbandes@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote">On Sun, Jan 17, 2016 at 5:56 PM, Rod Brown <span dir="ltr" class=""><<a href="mailto:rodney.brown6@icloud.com" target="_blank" class="">rodney.brown6@icloud.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="">While this isn’t in review yet, massive +1 from me. Good first implementation, and very welcome functionality.<div class=""><br class=""></div><div class="">Personally, I’m actually dealing with the difficulties of counts and enumerating enums in Obj-C and this is a pain in the neck. It’s not difficult, but it’s prone to breakage when someone alters code.</div></div></blockquote><div class=""><br class=""></div><div class="">If you're willing to share, I think it would help to have more examples of what problems people are trying to solve.</div><div class=""><br class=""></div><div class="">Jacob</div><div class=""> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><br class=""></div><div class="">This would be a vast improvement.</div><div class=""><br class=""></div><div class=""><br class=""><div class=""><blockquote type="cite" class=""><div class=""><div class="h5"><div class="">On 18 Jan 2016, at 10:44 AM, Jacob Bandes-Storch via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>> wrote:</div><br class=""></div></div><div class=""><div class=""><div class="h5"><div dir="ltr" class=""><div class=""><div class=""><div dir="ltr" class=""><div class=""><span style="font-size:12.8px" class="">Hi folks,</span><div style="font-size:12.8px" class=""><br class=""></div><div style="font-size:12.8px" class="">I've drafted a proposal to add a CaseEnumerable protocol, which will derive a static variable "cases" for enum types. Feedback is welcome, especially for refining the proposal before I submit a formal PR.</div><div style="font-size:12.8px" class=""><br class=""></div><div style="font-size:12.8px" class="">The draft is here; full text below. <a href="https://github.com/jtbandes/swift-evolution/blob/977a9923fd551491623b6bfd398d5859488fe1ae/proposals/0000-derived-collection-of-enum-cases.md" target="_blank" class="">https://github.com/jtbandes/swift-evolution/blob/977a9923fd551491623b6bfd398d5859488fe1ae/proposals/0000-derived-collection-of-enum-cases.md</a></div><div style="font-size:12.8px" class=""><br class=""></div><div style="font-size:12.8px" class=""><br clear="all" class=""><div class=""><div dir="ltr" class=""><h1 style="font-size:2.25em;margin-right:0px;margin-bottom:16px;margin-left:0px;line-height:1.2;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';margin-top:0px!important" class="">Derived Collection of Enum Cases</h1><ul style="padding:0px 0px 0px 2em;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px" class=""><li style="margin-left:15px" class="">Proposal: <a href="https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-derived-collection-of-enum-cases.md" style="color:rgb(64,120,192);text-decoration:none;background-color:transparent" target="_blank" class="">SE-NNNN</a></li><li style="margin-left:15px" class="">Author(s): <a href="https://github.com/jtbandes" style="color:rgb(64,120,192);text-decoration:none;background-color:transparent" target="_blank" class="">Jacob Bandes-Storch</a></li><li style="margin-left:15px" class="">Status: <strong class="">Awaiting review</strong></li><li style="margin-left:15px" class="">Review manager: TBD</li></ul><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'" class=""><a href="https://github.com/jtbandes/swift-evolution/blob/977a9923fd551491623b6bfd398d5859488fe1ae/proposals/0000-derived-collection-of-enum-cases.md#introduction" style="color:rgb(64,120,192);text-decoration:none;display:inline-block;padding-right:2px;line-height:1;background-color:transparent" target="_blank" class=""><span style="font-weight:normal;font-size:16px;line-height:1;font-family:octicons;display:inline-block;vertical-align:middle" class=""></span></a>Introduction</h2><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px" class="">It is a truth universally acknowledged, that a programmer in possession of an enum with many cases, must eventually be in want of dynamic enumeration over them.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px" class="">This topic has come up three times on the swift-evolution mailing list so far:</p><ul style="padding:0px 0px 0px 2em;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px" class=""><li style="margin-left:15px" class=""><a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151207/001233.html" style="color:rgb(64,120,192);text-decoration:none;background-color:transparent" target="_blank" class="">List of all Enum values (for simple enums)</a> (December 8, 2015)</li><li style="margin-left:15px" class=""><a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151221/003819.html" style="color:rgb(64,120,192);text-decoration:none;background-color:transparent" target="_blank" class="">Proposal: Enum 'count' functionality</a> (December 21, 2015)</li><li style="margin-left:15px" class=""><a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160111/006853.html" style="color:rgb(64,120,192);text-decoration:none;background-color:transparent" target="_blank" class="">Draft Proposal: count property for enum types</a> (January 17, 2016)</li></ul><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px" class="">Enumerating enumerations in Swift is also a popular topic on Stack Overflow:</p><ul style="padding:0px 0px 0px 2em;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px" class=""><li style="margin-left:15px" class=""><a href="http://stackoverflow.com/questions/24007461/how-to-enumerate-an-enum-with-string-type" style="color:rgb(64,120,192);text-decoration:none;background-color:transparent" target="_blank" class="">How to enumerate an enum with String type?</a> (June 3, 2014; question score 131)</li><li style="margin-left:15px" class=""><a href="http://stackoverflow.com/questions/27094878/how-do-i-get-the-count-of-a-swift-enum" style="color:rgb(64,120,192);text-decoration:none;background-color:transparent" target="_blank" class="">How do I get the count of a Swift enum?</a> (November 23, 2014; question score 37)</li></ul><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'" class=""><a href="https://github.com/jtbandes/swift-evolution/blob/977a9923fd551491623b6bfd398d5859488fe1ae/proposals/0000-derived-collection-of-enum-cases.md#motivation" style="color:rgb(64,120,192);text-decoration:none;display:inline-block;padding-right:2px;line-height:1;background-color:transparent" target="_blank" class=""><span style="font-weight:normal;font-size:16px;line-height:1;font-family:octicons;display:inline-block;vertical-align:middle" class=""></span></a>Motivation</h2><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px" class="">Simple enums are finite, and their values are statically known to the compiler, yet working with them programmatically is challenging. It is often desirable to iterate over all possible cases of an enum, or to know the number of cases (or maximum valid rawValue).</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px" class="">Currently, however, there is no built-in reflection or enumeration support. Users must resort to manually listing out cases in order to iterate over them:</p><div style="margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px" class=""><pre style="white-space:pre-wrap;overflow:auto;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;margin-top:0px;margin-bottom:0px;font-stretch:normal;line-height:1.45;padding:16px;border-radius:3px;word-wrap:normal;background-color:rgb(247,247,247)" class=""><span style="color:rgb(167,29,93)" class="">enum</span> Attribute {
<span style="color:rgb(167,29,93)" class="">case</span> Date, Name, Author
}
<span style="color:rgb(167,29,93)" class="">func</span> <span style="color:rgb(121,93,163)" class="">valueForAttribute</span>(attr: Attribute) <span style="color:rgb(167,29,93)" class="">-></span> <span style="color:rgb(0,134,179)" class="">String</span> { …from elsewhere… }
<span style="color:rgb(150,152,150)" class="">// Cases must be listed explicitly:</span>
[Attribute<span style="color:rgb(167,29,93)" class="">.</span>Date, <span style="color:rgb(167,29,93)" class="">.</span>Name, <span style="color:rgb(167,29,93)" class="">.</span>Author]<span style="color:rgb(167,29,93)" class="">.</span><span style="color:rgb(0,134,179)" class="">map</span>{ valueForAttribute($<span style="color:rgb(0,134,179)" class="">0</span>) }<span style="color:rgb(167,29,93)" class="">.</span>joinWithSeparator(<span style="color:rgb(24,54,145)" class="">"\n"</span>)</pre></div><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px" class="">For RawRepresentable enums, users have often relied on iterating over the known (or assumed) allowable raw values:</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px" class=""><em class="">Annotated excerpt from Nate Cook's post, <a href="http://natecook.com/blog/2014/10/loopy-random-enum-ideas/" style="color:rgb(64,120,192);text-decoration:none;background-color:transparent" target="_blank" class="">Loopy, Random Ideas for Extending "enum"</a> (October 2014):</em></p><div style="margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px" class=""><pre style="white-space:pre-wrap;overflow:auto;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;margin-top:0px;margin-bottom:0px;font-stretch:normal;line-height:1.45;padding:16px;border-radius:3px;word-wrap:normal;background-color:rgb(247,247,247)" class=""><span style="color:rgb(167,29,93)" class="">enum</span> Reindeer: <span style="color:rgb(0,134,179)" class="">Int</span> {
<span style="color:rgb(167,29,93)" class="">case</span> Dasher, Dancer, Prancer, Vixen, Comet, Cupid, Donner, Blitzen, Rudolph
}
<span style="color:rgb(167,29,93)" class="">extension</span> Reindeer {
<span style="color:rgb(167,29,93)" class="">static</span> <span style="color:rgb(167,29,93)" class="">var</span> allCases: [Reindeer] {
<span style="color:rgb(167,29,93)" class="">var</span> cur <span style="color:rgb(167,29,93)" class="">=</span> <span style="color:rgb(0,134,179)" class="">0</span>
<span style="color:rgb(167,29,93)" class="">return</span> <span style="color:rgb(0,134,179)" class="">Array</span>(
GeneratorOf<span style="color:rgb(167,29,93)" class=""><</span>Reindeer<span style="color:rgb(167,29,93)" class="">></span> {
<span style="color:rgb(167,29,93)" class="">return</span> Reindeer(rawValue: cur<span style="color:rgb(167,29,93)" class="">++</span>)
}
)
}
<span style="color:rgb(167,29,93)" class="">static</span> <span style="color:rgb(167,29,93)" class="">var</span> caseCount: <span style="color:rgb(0,134,179)" class="">Int</span> {
<span style="color:rgb(167,29,93)" class="">var</span> <span style="color:rgb(0,134,179)" class="">max</span>: <span style="color:rgb(0,134,179)" class="">Int</span> <span style="color:rgb(167,29,93)" class="">=</span> <span style="color:rgb(0,134,179)" class="">0</span>
<span style="color:rgb(167,29,93)" class="">while</span> <span style="color:rgb(167,29,93)" class="">let</span> _ <span style="color:rgb(167,29,93)" class="">=</span> <span style="color:rgb(167,29,93)" class="">self</span>(rawValue: <span style="color:rgb(167,29,93)" class="">++</span><span style="color:rgb(0,134,179)" class="">max</span>) {}
<span style="color:rgb(167,29,93)" class="">return</span> <span style="color:rgb(0,134,179)" class="">max</span>
}
<span style="color:rgb(167,29,93)" class="">static</span> <span style="color:rgb(167,29,93)" class="">func</span> <span style="color:rgb(121,93,163)" class="">randomCase</span>() <span style="color:rgb(167,29,93)" class="">-></span> Reindeer {
<span style="color:rgb(150,152,150)" class="">// everybody do the Int/UInt32 shuffle!</span>
<span style="color:rgb(167,29,93)" class="">let</span> randomValue <span style="color:rgb(167,29,93)" class="">=</span> <span style="color:rgb(0,134,179)" class="">Int</span>(arc4random_uniform(<span style="color:rgb(0,134,179)" class="">UInt32</span>(caseCount)))
<span style="color:rgb(167,29,93)" class="">return</span> <span style="color:rgb(167,29,93)" class="">self</span>(rawValue: randomValue)<span style="color:rgb(167,29,93)" class="">!</span>
}
}</pre></div><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px" class="">There are many problems with these existing techniques:</p><ul style="padding:0px 0px 0px 2em;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px" class=""><li style="margin-left:15px" class="">They are ad-hoc and can't benefit every enum type without duplicated and code.</li><li style="margin-left:15px" class="">They are not standardized across codebases, nor provided automatically by libraries such as Foundation and {App,UI}Kit.</li><li style="margin-left:15px" class="">They are sometimes prone to bugs when enum cases are added, but the user forgets to update a hard-coded static collection of cases.</li></ul><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'" class=""><a href="https://github.com/jtbandes/swift-evolution/blob/977a9923fd551491623b6bfd398d5859488fe1ae/proposals/0000-derived-collection-of-enum-cases.md#precedent-in-other-languages" style="color:rgb(64,120,192);text-decoration:none;display:inline-block;padding-right:2px;line-height:1;background-color:transparent" target="_blank" class=""><span style="font-weight:normal;font-size:16px;line-height:1;font-family:octicons;display:inline-block;vertical-align:middle" class=""></span></a>Precedent in other languages</h2><ul style="padding:0px 0px 0px 2em;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px" class=""><li style="margin-left:15px" class=""><p style="margin-top:16px;margin-bottom:16px" class="">Rust does not seem to have a solution for this problem.</p></li><li style="margin-left:15px" class=""><p style="margin-top:16px;margin-bottom:16px" class="">C#'s Enum has several <a href="https://msdn.microsoft.com/en-us/library/system.enum_methods.aspx" style="color:rgb(64,120,192);text-decoration:none;background-color:transparent" target="_blank" class="">methods</a> available for reflection, including <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">GetValues()</code> and <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">GetNames()</code>.</p></li><li style="margin-left:15px" class=""><p style="margin-top:16px;margin-bottom:16px" class="">Java <a href="http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.9.3" style="color:rgb(64,120,192);text-decoration:none;background-color:transparent" target="_blank" class="">implicitly declares</a> a static <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">values()</code> function, returning an array of enum values, and <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">valueOf(String name)</code> which takes a String and returns the enum value with the corresponding name (or throws an exception). More examples <a href="http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.9.3" style="color:rgb(64,120,192);text-decoration:none;background-color:transparent" target="_blank" class="">here</a>.</p></li><li style="margin-left:15px" class=""><p style="margin-top:16px;margin-bottom:16px" class="">The Template Haskell extension to Haskell provides a function <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">reify</code> which extracts <a href="http://hackage.haskell.org/package/template-haskell-2.10.0.0/docs/Language-Haskell-TH-Syntax.html#t:Info" style="color:rgb(64,120,192);text-decoration:none;background-color:transparent" target="_blank" class="">info about types</a>, including their constructors.</p></li></ul><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'" class=""><a href="https://github.com/jtbandes/swift-evolution/blob/977a9923fd551491623b6bfd398d5859488fe1ae/proposals/0000-derived-collection-of-enum-cases.md#proposed-solution" style="color:rgb(64,120,192);text-decoration:none;display:inline-block;padding-right:2px;line-height:1;background-color:transparent" target="_blank" class=""><span style="font-weight:normal;font-size:16px;line-height:1;font-family:octicons;display:inline-block;vertical-align:middle" class=""></span></a>Proposed solution</h2><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px" class="">Introduce a <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">CaseEnumerable</code> protocol. Conforming to CaseEnumerable will automagically derive a <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">static var cases</code>, whose type is a CollectionType of all the enum's values.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px" class="">Like <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">ErrorType</code>, the <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">CaseEnumerable</code> protocol will not have any user-visible requirements; merely adding the conformance is enough to enable case enumeration.</p><div style="margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px" class=""><pre style="white-space:pre-wrap;overflow:auto;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;margin-top:0px;margin-bottom:0px;font-stretch:normal;line-height:1.45;padding:16px;border-radius:3px;word-wrap:normal;background-color:rgb(247,247,247)" class=""><span style="color:rgb(167,29,93)" class="">enum</span> Ma { <span style="color:rgb(167,29,93)" class="">case</span> 马, 吗, 妈, 码, 骂, 🐎, 🐴 }
<span style="color:rgb(167,29,93)" class="">extension</span> Ma: CaseEnumerable {}
Ma<span style="color:rgb(167,29,93)" class="">.</span>cases <span style="color:rgb(150,152,150)" class="">// returns some CollectionType whose Generator.Element is Ma</span>
Ma<span style="color:rgb(167,29,93)" class="">.</span>cases<span style="color:rgb(167,29,93)" class="">.</span><span style="color:rgb(0,134,179)" class="">count</span> <span style="color:rgb(150,152,150)" class="">// returns 7</span>
<span style="color:rgb(0,134,179)" class="">Array</span>(Ma<span style="color:rgb(167,29,93)" class="">.</span>cases) <span style="color:rgb(150,152,150)" class="">// returns [Ma.马, .吗, .妈, .码, .骂, .🐎, .🐴]</span></pre></div><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px" class="">Conformances can even be added for enums which are defined in other modules:</p><div style="margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px" class=""><pre style="white-space:pre-wrap;overflow:auto;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;margin-top:0px;margin-bottom:0px;font-stretch:normal;line-height:1.45;padding:16px;border-radius:3px;word-wrap:normal;background-color:rgb(247,247,247)" class=""><span style="color:rgb(167,29,93)" class="">extension</span> NSTextAlignment: CaseEnumerable {}
<span style="color:rgb(0,134,179)" class="">Array</span>(NSTextAlignment<span style="color:rgb(167,29,93)" class="">.</span>cases) <span style="color:rgb(150,152,150)" class="">// returns [NSTextAlignment.Left, .Right, .Center, .Justified, .Natural]</span></pre></div><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'" class=""><a href="https://github.com/jtbandes/swift-evolution/blob/977a9923fd551491623b6bfd398d5859488fe1ae/proposals/0000-derived-collection-of-enum-cases.md#detailed-design" style="color:rgb(64,120,192);text-decoration:none;display:inline-block;padding-right:2px;line-height:1;background-color:transparent" target="_blank" class=""><span style="font-weight:normal;font-size:16px;line-height:1;font-family:octicons;display:inline-block;vertical-align:middle" class=""></span></a>Detailed design</h2><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px" class="">Enum cases are enumerated in the order they appear in the source code.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px" class="">The <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">cases</code> collection does not necessitate <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">Ω(number of cases)</code> static storage. For integer-backed enums, only the range(s) of valid rawValues need to be stored, and the enum construction can happen dynamically.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px" class="">Attempting to derive CaseEnumerable for a non-<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">enum</code> type will result in a compiler error.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px" class="">Attempting to derive CaseEnumerable for an enum with associated values will result in a compiler error.</p><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'" class=""><a href="https://github.com/jtbandes/swift-evolution/blob/977a9923fd551491623b6bfd398d5859488fe1ae/proposals/0000-derived-collection-of-enum-cases.md#possible-variations" style="color:rgb(64,120,192);text-decoration:none;display:inline-block;padding-right:2px;line-height:1;background-color:transparent" target="_blank" class=""><span style="font-weight:normal;font-size:16px;line-height:1;font-family:octicons;display:inline-block;vertical-align:middle" class=""></span></a>Possible variations</h2><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px" class="">I'd like us to discuss these, but they should be folded into either <em class="">Proposed solution</em> or <em class="">Future directions</em> before the proposal is submitted for review.</p><ul style="padding:0px 0px 0px 2em;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px" class=""><li style="margin-left:15px" class=""><p style="margin-top:16px;margin-bottom:16px" class="">For enums with raw values, a static <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">rawValues</code> property (a collection of <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">RawValue</code> rather than the enum type itself) could also be synthesized.</p></li><li style="margin-left:15px" class=""><p style="margin-top:16px;margin-bottom:16px" class="">CaseEnumerable could have a user-visible declaration requiring <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">static var cases</code>, which would allow users to add conformances for custom non-<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">enum</code> types.</p><ul style="padding:0px 0px 0px 2em;margin-top:0px;margin-bottom:0px" class=""><li style="margin-left:15px" class="">In this case, adding a conformance for a non-<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">enum</code> type would not be a compiler error, it would just require an explicit implementation of <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">static var cases</code>, since the compiler wouldn't synthesize it.</li><li style="margin-left:15px" class="">This would probably require <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">cases</code> to be <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">AnySequence<Self></code>, or to introduce an <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">AnyCollection</code>, since we aren't able to say <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">associatedtype CaseCollection: CollectionType where CaseCollection.Generator.Element == Self</code>.</li></ul></li><li style="margin-left:15px" class=""><p style="margin-top:16px;margin-bottom:16px" class="">It would be nice to have a way of supporting this for OptionSetType structs. I would recommend that <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">cases</code> for an OptionSetType should include only the already-declared static properties (not all possible combinations of them). However, I'm not sure it fits into this proposal.</p></li></ul><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'" class=""><a href="https://github.com/jtbandes/swift-evolution/blob/977a9923fd551491623b6bfd398d5859488fe1ae/proposals/0000-derived-collection-of-enum-cases.md#impact-on-existing-code" style="color:rgb(64,120,192);text-decoration:none;display:inline-block;padding-right:2px;line-height:1;background-color:transparent" target="_blank" class=""><span style="font-weight:normal;font-size:16px;line-height:1;font-family:octicons;display:inline-block;vertical-align:middle" class=""></span></a>Impact on existing code</h2><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px" class="">This proposal only adds functionality, so existing code will not be affected. (The identifier <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">CaseEnumerable</code> doesn't make any significant appearances in Google and GitHub searches.)</p><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'" class=""><a href="https://github.com/jtbandes/swift-evolution/blob/977a9923fd551491623b6bfd398d5859488fe1ae/proposals/0000-derived-collection-of-enum-cases.md#alternatives-considered" style="color:rgb(64,120,192);text-decoration:none;display:inline-block;padding-right:2px;line-height:1;background-color:transparent" target="_blank" class=""><span style="font-weight:normal;font-size:16px;line-height:1;font-family:octicons;display:inline-block;vertical-align:middle" class=""></span></a>Alternatives considered</h2><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px" class="">The community has not raised any solutions that differ significantly from this proposal, except for solutions which provide strictly <strong class="">more</strong> functionality. These are covered in the next section, <em class="">Future directions</em>.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px" class="">An alternative is to <em class="">not</em> implement this feature. The cons of this are discussed in the <em class="">Motivation</em> section above.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px" class="">The functionality could also be provided entirely through the Mirror/reflection APIs, but this would result in much more obscure and confusing usage patterns.</p><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'" class=""><a href="https://github.com/jtbandes/swift-evolution/blob/977a9923fd551491623b6bfd398d5859488fe1ae/proposals/0000-derived-collection-of-enum-cases.md#future-directions" style="color:rgb(64,120,192);text-decoration:none;display:inline-block;padding-right:2px;line-height:1;background-color:transparent" target="_blank" class=""><span style="font-weight:normal;font-size:16px;line-height:1;font-family:octicons;display:inline-block;vertical-align:middle" class=""></span></a>Future directions</h2><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px" class="">Many people would be happy to see even more functionality than what's proposed here. I'm keeping this proposal intentionally limited, but I hope the community can continue discussing the topic to flesh out more features.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px" class="">Here are some starting points, which are <strong class="">not</strong> part of this proposal:</p><ul style="padding:0px 0px 0px 2em;margin-top:0px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;line-height:25.6px;margin-bottom:0px!important" class=""><li style="margin-left:15px" class=""><p style="margin-top:16px;margin-bottom:16px" class="">Support for enum case <strong class="">names</strong>. It would be useful to get case names even for enums which have integer rawValues. This could be part of the existing reflection APIs, or it could take the form of derived implementations of StringLiteralConvertible/CustomStringConvertible.</p></li><li style="margin-left:15px" class=""><p style="margin-top:16px;margin-bottom:16px" class="">Support for enums with associated values.</p><ul style="padding:0px 0px 0px 2em;margin-top:0px;margin-bottom:0px" class=""><li style="margin-left:15px" class=""><p style="margin-top:16px;margin-bottom:16px" class="">When all associated values are themselves CaseEnumerable, this could happen automatically:</p><div style="margin-bottom:16px" class=""><pre style="white-space:pre-wrap;overflow:auto;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;margin-top:0px;margin-bottom:0px;font-stretch:normal;line-height:1.45;padding:16px;border-radius:3px;word-wrap:normal;background-color:rgb(247,247,247)" class=""><span style="color:rgb(167,29,93)" class="">enum</span> Suit: CaseEnumerable { <span style="color:rgb(167,29,93)" class="">case</span> Spades, Hearts, Diamonds, Clubs }
<span style="color:rgb(167,29,93)" class="">enum</span> Rank: <span style="color:rgb(0,134,179)" class="">Int</span>, CaseEnumerable {
<span style="color:rgb(167,29,93)" class="">case</span> Ace <span style="color:rgb(167,29,93)" class="">=</span> <span style="color:rgb(0,134,179)" class="">1</span>, Two, Three, Four, Five, Six
<span style="color:rgb(167,29,93)" class="">case</span> Seven, Eight, Nine, Ten, Jack, Queen, King
}
<span style="color:rgb(167,29,93)" class="">enum</span> Card {
<span style="color:rgb(167,29,93)" class="">case</span> Joker
<span style="color:rgb(167,29,93)" class="">case</span> Value(Rank, Suit)
}
<span style="color:rgb(150,152,150)" class="">// This now works, and generates all possible card types (Joker, Value(Ace, Spades), ...)</span>
<span style="color:rgb(167,29,93)" class="">extension</span> Card: CaseEnumerable {}</pre></div></li><li style="margin-left:15px" class=""><p style="margin-top:16px;margin-bottom:16px" class="">If associated values aren't CaseEnumerable, but all cases are homogeneous, the <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">cases</code> collection could vend functions of <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">AssociatedValueType -> EnumType</code>:</p><div style="margin-bottom:16px" class=""><pre style="white-space:pre-wrap;overflow:auto;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;margin-top:0px;margin-bottom:0px;font-stretch:normal;line-height:1.45;padding:16px;border-radius:3px;word-wrap:normal;background-color:rgb(247,247,247)" class=""><span style="color:rgb(167,29,93)" class="">enum</span> LogMessage { <span style="color:rgb(167,29,93)" class="">case</span> Error(<span style="color:rgb(0,134,179)" class="">String</span>), Warning(<span style="color:rgb(0,134,179)" class="">String</span>), Info(<span style="color:rgb(0,134,179)" class="">String</span>) }
<span style="color:rgb(167,29,93)" class="">extension</span> LogMessage: CaseEnumerable {}
LogMessage<span style="color:rgb(167,29,93)" class="">.</span>cases <span style="color:rgb(150,152,150)" class="">// elements are (String) -> LogMessage</span></pre></div></li><li style="margin-left:15px" class=""><p style="margin-top:16px;margin-bottom:16px" class="">If Swift had anonymous sum types like <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">A | B | C</code>, then <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">E.cases</code> could vend elements of type <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)" class="">A->E | B->E | C->E</code>.</p><div style="margin-bottom:16px" class=""><pre style="white-space:pre-wrap;overflow:auto;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;margin-top:0px;margin-bottom:0px;font-stretch:normal;line-height:1.45;padding:16px;border-radius:3px;word-wrap:normal;background-color:rgb(247,247,247)" class=""><span style="color:rgb(167,29,93)" class="">enum</span> Expr { <span style="color:rgb(167,29,93)" class="">case</span> Apply(Expr, Expr), Tuple(Expr, Expr), Literal(<span style="color:rgb(0,134,179)" class="">Int</span>) }
<span style="color:rgb(167,29,93)" class="">extension</span> Value: CaseEnumerable {}
<span style="color:rgb(150,152,150)" class="">// This example is pretty contrived, but illustrates the functionality.</span>
<span style="color:rgb(167,29,93)" class="">let</span> fortyTwos <span style="color:rgb(167,29,93)" class="">=</span> Expr<span style="color:rgb(167,29,93)" class="">.</span>cases<span style="color:rgb(167,29,93)" class="">.</span><span style="color:rgb(0,134,179)" class="">map</span> {
<span style="color:rgb(150,152,150)" class="">// $0 is of type `Int -> Expr | (Expr, Expr) -> Expr`</span>
<span style="color:rgb(167,29,93)" class="">switch</span> $<span style="color:rgb(0,134,179)" class="">0</span> {
<span style="color:rgb(167,29,93)" class="">case</span> <span style="color:rgb(167,29,93)" class="">let</span> lit <span style="color:rgb(167,29,93)" class="">as</span> <span style="color:rgb(0,134,179)" class="">Int</span> <span style="color:rgb(167,29,93)" class="">-></span> Expr: <span style="color:rgb(150,152,150)" class="">// handles .Literal</span>
<span style="color:rgb(167,29,93)" class="">return</span> lit(<span style="color:rgb(0,134,179)" class="">42</span>)
<span style="color:rgb(167,29,93)" class="">case</span> <span style="color:rgb(167,29,93)" class="">let</span> bin <span style="color:rgb(167,29,93)" class="">as</span> (Expr, Expr) <span style="color:rgb(167,29,93)" class="">-></span> Expr: <span style="color:rgb(150,152,150)" class="">// handles .Apply and .Tuple</span>
<span style="color:rgb(167,29,93)" class="">return</span> bin(<span style="color:rgb(167,29,93)" class="">.</span>Literal(<span style="color:rgb(0,134,179)" class="">42</span>), <span style="color:rgb(167,29,93)" class="">.</span>Literal(<span style="color:rgb(0,134,179)" class="">42</span>))
<span style="color:rgb(150,152,150)" class="">// all cases are covered</span>
}
}</pre></div></li></ul></li><li style="margin-left:15px" class=""><p style="margin-top:16px;margin-bottom:16px" class="">Support for generic enums.</p><ul style="padding:0px 0px 0px 2em;margin-top:0px;margin-bottom:0px" class=""><li style="margin-left:15px" class=""><p style="margin-top:16px;margin-bottom:16px" class="">CaseEnumerable could be conditionally supported depending on the generic argument(s). A great example would be Optional:</p><div style="margin-bottom:16px" class=""><pre style="white-space:pre-wrap;overflow:auto;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;margin-top:0px;margin-bottom:0px;font-stretch:normal;line-height:1.45;padding:16px;border-radius:3px;word-wrap:normal;background-color:rgb(247,247,247)" class=""><span style="color:rgb(167,29,93)" class="">enum</span> MyEnum: CaseEnumerable {}
<span style="color:rgb(167,29,93)" class="">extension</span> <span style="color:rgb(0,134,179)" class="">Optional</span>: CaseEnumerable <span style="color:rgb(167,29,93)" class="">where</span> Wrapped: CaseEnumerable {}
<span style="color:rgb(150,152,150)" class="">// Optional<MyEnum>.cases effectively contains `MyEnum.cases + [.None]`</span></pre></div></li></ul></li></ul></div></div></div></div></div></div></div>
</div></div></div>
_______________________________________________<span class=""><br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></span></div></blockquote></div><br class=""></div></div></blockquote></div><br class=""></div></div>
</div></blockquote></div><br class=""></body></html>