1 /*
2   ==============================================================================
3 
4    This file is part of the JUCE library.
5    Copyright (c) 2020 - Raw Material Software Limited
6 
7    JUCE is an open source library subject to commercial or open-source
8    licensing.
9 
10    The code included in this file is provided under the terms of the ISC license
11    http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12    To use, copy, modify, and/or distribute this software for any purpose with or
13    without fee is hereby granted provided that the above copyright notice and
14    this permission notice appear in all copies.
15 
16    JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17    EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18    DISCLAIMED.
19 
20   ==============================================================================
21 */
22 
23 namespace juce
24 {
25 
26 //==============================================================================
27 /**
28     Represents a string identifier, designed for accessing properties by name.
29 
30     Comparing two Identifier objects is very fast (an O(1) operation), but creating
31     them can be slower than just using a String directly, so the optimal way to use them
32     is to keep some static Identifier objects for the things you use often.
33 
34     @see NamedValueSet, ValueTree
35 
36     @tags{Core}
37 */
38 class JUCE_API  Identifier  final
39 {
40 public:
41     /** Creates a null identifier. */
42     Identifier() noexcept;
43 
44     /** Creates an identifier with a specified name.
45         Because this name may need to be used in contexts such as script variables or XML
46         tags, it must only contain ascii letters and digits, or the underscore character.
47     */
48     Identifier (const char* name);
49 
50     /** Creates an identifier with a specified name.
51         Because this name may need to be used in contexts such as script variables or XML
52         tags, it must only contain ascii letters and digits, or the underscore character.
53     */
54     Identifier (const String& name);
55 
56     /** Creates an identifier with a specified name.
57         Because this name may need to be used in contexts such as script variables or XML
58         tags, it must only contain ascii letters and digits, or the underscore character.
59     */
60     Identifier (String::CharPointerType nameStart, String::CharPointerType nameEnd);
61 
62     /** Creates a copy of another identifier. */
63     Identifier (const Identifier& other) noexcept;
64 
65     /** Creates a copy of another identifier. */
66     Identifier& operator= (const Identifier& other) noexcept;
67 
68     /** Creates a copy of another identifier. */
69     Identifier (Identifier&& other) noexcept;
70 
71     /** Creates a copy of another identifier. */
72     Identifier& operator= (Identifier&& other) noexcept;
73 
74     /** Destructor */
75     ~Identifier() noexcept;
76 
77     /** Compares two identifiers. This is a very fast operation. */
78     inline bool operator== (const Identifier& other) const noexcept     { return name.getCharPointer() == other.name.getCharPointer(); }
79 
80     /** Compares two identifiers. This is a very fast operation. */
81     inline bool operator!= (const Identifier& other) const noexcept     { return name.getCharPointer() != other.name.getCharPointer(); }
82 
83     /** Compares the identifier with a string. */
84     inline bool operator== (StringRef other) const noexcept             { return name == other; }
85 
86     /** Compares the identifier with a string. */
87     inline bool operator!= (StringRef other) const noexcept             { return name != other; }
88 
89     /** Compares the identifier with a string. */
90     inline bool operator<  (StringRef other) const noexcept             { return name <  other; }
91 
92     /** Compares the identifier with a string. */
93     inline bool operator<= (StringRef other) const noexcept             { return name <= other; }
94 
95     /** Compares the identifier with a string. */
96     inline bool operator>  (StringRef other) const noexcept             { return name >  other; }
97 
98     /** Compares the identifier with a string. */
99     inline bool operator>= (StringRef other) const noexcept             { return name >= other; }
100 
101     /** Returns this identifier as a string. */
toString()102     const String& toString() const noexcept                             { return name; }
103 
104     /** Returns this identifier's raw string pointer. */
CharPointerType()105     operator String::CharPointerType() const noexcept                   { return name.getCharPointer(); }
106 
107     /** Returns this identifier's raw string pointer. */
getCharPointer()108     String::CharPointerType getCharPointer() const noexcept             { return name.getCharPointer(); }
109 
110     /** Returns this identifier as a StringRef. */
StringRef()111     operator StringRef() const noexcept                                 { return name; }
112 
113     /** Returns true if this Identifier is not null */
isValid()114     bool isValid() const noexcept                                       { return name.isNotEmpty(); }
115 
116     /** Returns true if this Identifier is null */
isNull()117     bool isNull() const noexcept                                        { return name.isEmpty(); }
118 
119     /** A null identifier. */
120     static Identifier null;
121 
122     /** Checks a given string for characters that might not be valid in an Identifier.
123         Since Identifiers are used as a script variables and XML attributes, they should only contain
124         alphanumeric characters, underscores, or the '-' and ':' characters.
125     */
126     static bool isValidIdentifier (const String& possibleIdentifier) noexcept;
127 
128 private:
129     String name;
130 };
131 
132 } // namespace juce
133