xtd 0.2.0
Loading...
Searching...
No Matches
enum_object.hpp
Go to the documentation of this file.
1
4#pragma once
5#include "array.hpp"
6#include "enum_attribute.hpp"
7#include "enum_collection.hpp"
8#include "enum_register.hpp"
10#include "format_exception.hpp"
11#include "icomparable.hpp"
12#include "iequatable.hpp"
13#include "iformatable.hpp"
14#include "number_styles.hpp"
15#include "optional.hpp"
16#include "static.hpp"
17#include "string_comparison.hpp"
19
21namespace xtd {
23
47 template<class enum_t = std::nullptr_t>
48 struct enum_object : xtd::object, xtd::icomparable<enum_object<enum_t>>, xtd::iequatable<enum_object<enum_t >>, xtd::iformatable {
50
53 using enum_type = enum_t;
55 using value_type = enum_t;
57
59
62 enum_object() noexcept = default;
67
69 explicit enum_object(xtd::byte value) : value(to_enum(value)) {}
70 explicit enum_object(sbyte value) : value(to_enum(value)) {}
71 explicit enum_object(int16 value) : value(to_enum(value)) {}
72 explicit enum_object(int32 value) : value(to_enum(value)) {}
73 explicit enum_object(int64 value) : value(to_enum(value)) {}
74 explicit enum_object(uint16 value) : value(to_enum(value)) {}
75 explicit enum_object(uint32 value) : value(to_enum(value)) {}
76 explicit enum_object(uint64 value) : value(to_enum(value)) {}
77 enum_object(enum_object&&) noexcept = default;
78 enum_object(const enum_object&) noexcept = default;
79 enum_object& operator =(const enum_object&) noexcept = default;
80 operator enum_type() const noexcept {return value;}
82
84
90 bool has_flag(enum_type flag) const noexcept {return (to_int(value) & to_int(flag)) == to_int(flag);}
91
96
98
110 int32 compare_to(const enum_object& value) const noexcept override {
111 if (to_int(this->value) == to_int(value.value)) return 0;
112 if (to_int(this->value) < to_int(value.value)) return -1;
113 return 1;
114 }
115
119 bool equals(const object& obj) const noexcept override {return dynamic_cast<const enum_object*>(&obj) && equals(static_cast<const enum_object&>(obj));}
123 bool equals(const enum_object& value) const noexcept override {return this->value == value.value;}
127 bool equals(enum_type value) const noexcept {return this->value == value;}
131 template<class attribute_t>
132 bool equals(attribute_t value) const noexcept {return false;}
133
136 xtd::size get_hash_code() const noexcept override {return hash_code::combine(value);}
137
140 xtd::byte to_byte() const noexcept {return static_cast<xtd::byte>(value);}
141
144 int16 to_int16() const noexcept {return static_cast<int16>(value);}
145
148 int32 to_int32() const noexcept {return static_cast<int32>(value);}
149
152 int64 to_int64() const noexcept {return static_cast<int64>(value);}
153
156 sbyte to_sbyte() const noexcept {return static_cast<sbyte>(value);}
157
160 uint16 to_uint16() const noexcept {return static_cast<uint16>(value);}
161
164 uint32 to_uint32() const noexcept {return static_cast<uint32>(value);}
165
168 uint64 to_uint64() const noexcept {return static_cast<uint64>(value);}
169
172 xtd::string to_string() const noexcept override {
173 init();
174 if (attribute() == xtd::enum_attribute::flags) return to_string_flags();
175
176 auto iterator = std::find_if(entries().begin(), entries().end(), [&](auto value)->bool {return value.first == this->value;});
177 if (iterator == entries().end()) return string::format("{}", to_int(value));
178
179 return iterator->second;
180 }
181
198 xtd::string to_string(const xtd::string& format) const {return to_string(format, std::locale {});}
199
219
221
227 static enum_type parse(const xtd::string& str) {return parse(str, false);}
232 static enum_type parse(const xtd::string& str, bool ignore_case) {
233 enum_object<enum_type>().init();
234 if (enum_object<enum_type>().attribute() == xtd::enum_attribute::flags) return parse_flags(str, ignore_case);
235
236 for (auto item : enum_object<enum_type>().entries()) {
237 if (xtd::string::compare(str, item.second, ignore_case) == 0)
238 return static_cast<enum_type>(item.first);
239 }
240
241 return to_enum(xtd::parse<int64>(str));
242 }
244
245
247 friend auto operator << (std::ostream& os, const enum_object& value) -> std::ostream& {return os << value.to_string();}
249
250 private:
251 friend struct enum_object<std::nullptr_t>;
252
253 xtd::string get_name() const noexcept {
254 auto iterator = std::find_if(entries().begin(), entries().end(), [&](auto value)->bool {return value.first == this->value;});
255 if (iterator == entries().end()) return xtd::string::format("{}", to_int(value));
256 return iterator->second;
257 }
258
259 static enum_type parse_flags(const xtd::string& value, bool ignore_case) {
260 xtd::array<xtd::string> values = value.split(',');
261 for (xtd::string& str : values)
262 str = str.trim(' ');
263
264 if (values.length() == 1) {
265 for (auto item : enum_object<enum_type>().entries()) {
266 if (xtd::string::compare(value, item.second, ignore_case) == 0)
267 return to_enum(item.first);
268 }
269 return to_enum(xtd::parse<int64>(value));
270 }
271
272 int64 result = 0;
273 for (xtd::string str : values) {
274 bool found = false;
275 for (auto item : enum_object<enum_type>().entries()) {
276 if (xtd::string::compare(str, item.second, ignore_case) == 0) {
277 found = true;
278 result |= to_int(item.first);
279 break;
280 }
281 }
282 if (found == false)
284 }
285
286 return to_enum(result);
287 }
288
289 xtd::string to_string_flags() const noexcept {
290 auto iterator = std::find_if(entries().begin(), entries().end(), [&](auto value)->bool {return value.first == this->value;});
291 if (to_int(value) == 0 && iterator == entries().end()) return "0";
292
293 iterator = std::find_if(entries().begin(), entries().end(), [&](auto value)->bool {return value.first == to_enum(0);});
294 if (to_int(value) == 0) return iterator == entries().end() ? "0" : iterator->second;
295
296 xtd::string str;
297 int64 rest = to_int(value);
298 enum_collection<enum_type> reversed_entries = entries();
299 std::reverse(reversed_entries.begin(), reversed_entries.end());
300
301 for (auto item : reversed_entries) {
302 if (to_int(item.first) != 0 && (rest & to_int(item.first)) == to_int(item.first)) {
303 rest -= to_int(item.first);
304 if (!xtd::string::is_empty(str)) str = ", " + str;
305 str = item.second + str;
306 }
307 }
308
309 if (xtd::string::is_empty(str) || rest > 0) return xtd::string::format("{}", to_int(value));
310
311 return str;
312 }
313
314 template<class attribute_t>
315 inline static enum_type to_enum(attribute_t value) noexcept {return static_cast<enum_type>(value);}
316 static int64 to_int(enum_type value) noexcept {return static_cast<int64>(value);}
317
318 static xtd::enum_attribute attribute() noexcept {
319 if (attribute_.has_value()) return attribute_.value();
320 attribute_ = xtd::enum_attribute(enum_set_attribute<enum_type>());
321 return attribute_.value();
322 }
323
324 static enum_collection<enum_type>& entries() noexcept {
325 if (entries_.has_value()) return entries_.value();
326 entries_ = enum_collection<enum_type>(enum_register<enum_type>());
327 return entries_.value();
328 };
329
330 static void init() noexcept {
331 attribute();
332 entries();
333 }
334
335 inline static std::optional<xtd::enum_attribute> attribute_;
336 inline static std::optional<enum_collection<enum_type>> entries_;
337 };
338
349 template<>
350 struct enum_object < std::nullptr_t > static_ {
352
355
358
362 template < class enum_t >
363 inline static const xtd::enum_collection < enum_t >& get_entries() noexcept {
364 return enum_object < enum_t > ().entries();
365 }
366
369 template < class enum_t >
370 inline static xtd::enum_collection < xtd::byte > get_entries_as_byte() noexcept {
372 std::for_each(enum_object < enum_t > ().entries().begin(), enum_object < enum_t>().entries().end(), [&](auto entry) {entries.emplace_back(enum_object < enum_t > (entry.first).to_byte(), entry.second);});
373 return entries;
374 }
375
378 template < class enum_t >
379 inline static xtd::enum_collection < int16 > get_entries_as_int16() noexcept {
381 std::for_each(enum_object < enum_t > ().entries().begin(), enum_object < enum_t>().entries().end(), [&](auto entry) {entries.emplace_back(enum_object < enum_t > (entry.first).to_int16(), entry.second);});
382 return entries;
383 }
384
387 template < class enum_t >
388 inline static xtd::enum_collection < int32 > get_entries_as_int32() noexcept {
390 std::for_each(enum_object < enum_t > ().entries().begin(), enum_object < enum_t>().entries().end(), [&](auto entry) {entries.emplace_back(enum_object < enum_t > (entry.first).to_int32(), entry.second);});
391 return entries;
392 }
393
396 template < class enum_t >
397 inline static xtd::enum_collection < int64 > get_entries_as_int64() noexcept {
399 std::for_each(enum_object < enum_t > ().entries().begin(), enum_object < enum_t>().entries().end(), [&](auto entry) {entries.emplace_back(enum_object < enum_t > (entry.first).to_int64(), entry.second);});
400 return entries;
401 }
402
405 template < class enum_t >
406 inline static xtd::enum_collection < sbyte > get_entries_as_sbyte() noexcept {
408 std::for_each(enum_object < enum_t > ().entries().begin(), enum_object < enum_t>().entries().end(), [&](auto entry) {entries.emplace_back(enum_object < enum_t > (entry.first).to_sbyte(), entry.second);});
409 return entries;
410 }
411
414 template < class enum_t >
415 inline static xtd::enum_collection < uint16 > get_entries_as_uint16() noexcept {
417 std::for_each(enum_object < enum_t > ().entries().begin(), enum_object < enum_t>().entries().end(), [&](auto entry) {entries.emplace_back(enum_object < enum_t > (entry.first).to_uint16(), entry.second);});
418 return entries;
419 }
420
423 template < class enum_t >
424 inline static xtd::enum_collection < uint32 > get_entries_as_uint32() noexcept {
426 std::for_each(enum_object < enum_t > ().entries().begin(), enum_object < enum_t>().entries().end(), [&](auto entry) {entries.emplace_back(enum_object < enum_t > (entry.first).to_uint32(), entry.second);});
427 return entries;
428 }
429
432 template < class enum_t >
433 inline static xtd::enum_collection < uint64 > get_entries_as_uint64() noexcept {
435 std::for_each(enum_object < enum_t > ().entries().begin(), enum_object < enum_t>().entries().end(), [&](auto entry) {entries.emplace_back(enum_object < enum_t > (entry.first).to_uint64(), entry.second);});
436 return entries;
437 }
438
443 template < class enum_t >
444 inline static xtd::string get_name(enum_t value) noexcept {return enum_object < enum_t > (value).to_string();}
449 template < class enum_t >
450 inline static xtd::string get_name(enum_object < enum_t > value) noexcept {return enum_object < enum_t > (value).to_string();}
455 template < class enum_t >
456 inline static xtd::string get_name(int32 value) noexcept {return enum_object < enum_t > (value).to_string();}
461 template < class enum_t >
462 inline static xtd::string get_name(int64 value) noexcept {return enum_object < enum_t > (value).to_string();}
463
467 template < class enum_t >
468 inline static xtd::array < xtd::string > get_names() noexcept {
469 auto names = xtd::array < xtd::string > {};
470 std::for_each(enum_object < enum_t > ().entries().begin(), enum_object < enum_t > ().entries().end(), [&](auto entry) {names.resize(names.length() + 1, entry.second);});
471 return names;
472 }
473
477 template < class enum_t >
478 inline static xtd::array < enum_t > get_values() noexcept {
479 auto values = xtd::array < enum_t > {};
480 std::for_each(enum_object < enum_t > ().entries().begin(), enum_object < enum_t > ().entries().end(), [&](auto entry) {values.resize(values.length() + 1, entry.first);});
481 return values;
482 }
483
487 template < class enum_t >
488 inline static xtd::array < xtd::byte > get_values_as_byte() noexcept {
489 auto values = xtd::array < xtd::byte > {};
490 std::for_each(enum_object < enum_t > ().entries().begin(), enum_object < enum_t > ().entries().end(), [&](auto entry) {values.resize(values.length() + 1, enum_object < enum_t > (entry.first).to_byte());});
491 return values;
492 }
493
497 template < class enum_t >
498 inline static xtd::array < int16 > get_values_as_int16() noexcept {
499 auto values = xtd::array < xtd::int16 > {};
500 std::for_each(enum_object < enum_t > ().entries().begin(), enum_object < enum_t > ().entries().end(), [&](auto entry) {values.resize(values.length() + 1, enum_object < enum_t > (entry.first).to_int16());});
501 return values;
502 }
503
507 template < class enum_t >
508 inline static xtd::array < int32 > get_values_as_int32() noexcept {
509 auto values = xtd::array < xtd::int32 > {};
510 std::for_each(enum_object < enum_t > ().entries().begin(), enum_object < enum_t > ().entries().end(), [&](auto entry) {values.resize(values.length() + 1, enum_object < enum_t > (entry.first).to_int32());});
511 return values;
512 }
513
517 template < class enum_t >
518 inline static xtd::array < int64 > get_values_as_int64() noexcept {
519 auto values = xtd::array < xtd::int64 > {};
520 std::for_each(enum_object < enum_t > ().entries().begin(), enum_object < enum_t > ().entries().end(), [&](auto entry) {values.resize(values.length() + 1, enum_object < enum_t > (entry.first).to_int64());});
521 return values;
522 }
523
527 template < class enum_t >
528 inline static xtd::array < sbyte > get_values_as_sbyte() noexcept {
529 auto values = xtd::array < xtd::sbyte > {};
530 std::for_each(enum_object < enum_t > ().entries().begin(), enum_object < enum_t > ().entries().end(), [&](auto entry) {values.resize(values.length() + 1, enum_object < enum_t > (entry.first).to_sbyte());});
531 return values;
532 }
533
537 template < class enum_t >
538 inline static xtd::array < uint16 > get_values_as_uint16() noexcept {
539 auto values = xtd::array < xtd::uint16 > {};
540 std::for_each(enum_object < enum_t > ().entries().begin(), enum_object < enum_t > ().entries().end(), [&](auto entry) {values.resize(values.length() + 1, enum_object < enum_t > (entry.first).to_uint16());});
541 return values;
542 }
543
547 template < class enum_t >
548 inline static xtd::array < uint32 > get_values_as_uint32() noexcept {
549 auto values = xtd::array < xtd::uint32 > {};
550 std::for_each(enum_object < enum_t > ().entries().begin(), enum_object < enum_t > ().entries().end(), [&](auto entry) {values.resize(values.length() + 1, enum_object < enum_t > (entry.first).to_uint32());});
551 return values;
552 }
553
557 template < class enum_t >
558 inline static xtd::array < uint64 > get_values_as_uint64() noexcept {
559 auto values = xtd::array < xtd::uint64 > {};
560 std::for_each(enum_object < enum_t > ().entries().begin(), enum_object < enum_t > ().entries().end(), [&](auto entry) {values.resize(values.length() + 1, enum_object < enum_t > (entry.first).to_uint64());});
561 return values;
562 }
563
568 template < class enum_t >
569 inline static bool is_defined(enum_t value) noexcept {return std::find_if(enum_object < enum_t > ().entries().begin(), enum_object < enum_t>().entries().end(), [&](auto item)->bool {return item.first == value;}) != enum_object < enum_t > ().entries().end();}
574 template < class enum_t >
575 inline static bool is_defined(enum_object < enum_t > value) noexcept {return std::find_if(enum_object < enum_t>().entries().begin(), enum_object<enum_t>().entries().end(), [&](auto item)->bool {return item.first == value;}) != enum_object < enum_t > ().entries().end();}
576
581 template < class enum_t >
582 inline static enum_t parse(const xtd::string & value) {return parse < enum_t > (value, false);}
588 template < class enum_t >
589 inline static enum_t parse(const xtd::string & str, bool ignore_case) {
590 return enum_object < enum_t >::parse(str, ignore_case);
591 }
592
596 template < class enum_t >
597 inline static xtd::byte to_byte(enum_t value) noexcept {return enum_object < enum_t > (value).to_byte();}
598
602 template < class enum_t >
603 inline static int16 to_int16(enum_t value) noexcept {return enum_object < enum_t > (value).to_int16();}
604
608 template < class enum_t >
609 inline static int32 to_int32(enum_t value) noexcept {return enum_object < enum_t > (value).to_int32();}
610
614 template < class enum_t >
615 inline static int64 to_int64(enum_t value) noexcept {return enum_object < enum_t > (value).to_int64();}
616
620 template < class enum_t >
621 inline static sbyte to_sbyte(enum_t value) noexcept {return enum_object < enum_t > (value).to_sbyte();}
622
626 template < class enum_t >
627 inline static xtd::string to_string(enum_t value) noexcept {return enum_object < enum_t > (value).to_string();}
628
632 template < class enum_t >
633 inline static uint16 to_uint16(enum_t value) noexcept {return enum_object < enum_t > (value).to_uint16();}
634
638 template < class enum_t >
639 inline static uint32 to_uint32(enum_t value) noexcept {return enum_object < enum_t > (value).to_uint32();}
640
644 template < class enum_t >
645 inline static uint64 to_uint64(enum_t value) noexcept {return enum_object < enum_t > (value).to_uint64();}
646
651 template < class enum_t >
652 inline static bool try_parse(const xtd::string & value, enum_t& result) noexcept {return try_parse < enum_t > (value, false, result);}
653
659 template < class enum_t >
660 inline static bool try_parse(const xtd::string & value, bool ignore_case, enum_t& result) noexcept {
661 try {
662 result = parse < enum_t > (value, ignore_case);
663 return true;
664 } catch (...) {
665 return false;
666 }
667 }
669 };
670
671}
672
674template < class enum_t >
675inline std::string __enum_to_string__(enum_t value) noexcept {
676 return xtd::enum_object < >::get_name(value);
677}
678
679template < class value_t >
680value_t __parse_enum(const std::string& str) {
681 return xtd::enum_object < >::parse < value_t > (str);
682}
Contains xtd::array class.
Represents the base class for custom attributes.
Definition attribute.hpp:25
basic_string trim() const noexcept
Removes all leading and trailing occurrences of white-space characters from the specified xtd::basic_...
Definition basic_string.hpp:1408
bool is_empty() const noexcept
Definition basic_string.hpp:3035
virtual auto end() const -> const_iterator
Returns an iterator to the element following the last element of the enumerable.
Definition enumerable_iterators.hpp:155
Provides information about a specific culture (called a locale for unmanaged code development)....
Definition culture_info.hpp:43
static xtd::size combine(args_t... values) noexcept
Combines values into a hash code.
Definition hash_code.hpp:70
static void throws(xtd::helpers::exception_case exception_case, const source_location &location=source_location::current())
Throws an exption with specified exception case.
Defines a generalized comparison method that a value type or class implements to create a type-specif...
Definition icomparable.hpp:21
Defines a generalized method that a value type or class implements to create a type-specific method f...
Definition iequatable.hpp:22
Provides functionality to format the value of an object into a string representation.
Definition iformatable.hpp:42
Supports all classes in the xtd class hierarchy and provides low-level services to derived classes....
Definition object.hpp:45
Contains xtd::enum_attribute enum class.
Contains xtd::enum_collection.
Contains xtd::enum_register.
Contains xtd::enum_set_attribute strcut.
Contains xtd::format_exception exception.
static basic_string format(const basic_string< char > &fmt, args_t &&... args)
xtd::string format(const xtd::string &fmt, args_t &&... args)
Writes the text representation of the specified arguments list, to string using the specified format ...
Definition format.hpp:21
@ format
The format is not valid.
Definition exception_case.hpp:51
#define static_
This keyword is use to represent a static object. A static object can't be instantiated (constructors...
Definition static.hpp:37
xtd::basic_string< char > string
Represents text as a sequence of UTF-8 code units.
Definition __string_definitions.hpp:43
std::int64_t int64
Represents a 64-bit signed integer.
Definition int64.hpp:23
std::uint32_t uint32
Represents a 32-bit unsigned integer.
Definition uint32.hpp:23
size_t size
Represents a size of any object in bytes.
Definition size.hpp:23
std::int8_t sbyte
Represents a 8-bit signed integer.
Definition sbyte.hpp:23
std::uint16_t uint16
Represents a 16-bit unsigned integer.
Definition uint16.hpp:23
std::int32_t int32
Represents a 32-bit signed integer.
Definition int32.hpp:23
std::int16_t int16
Represents a 16-bit signed integer.
Definition int16.hpp:23
std::uint64_t uint64
Represents a 64-bit unsigned integer.
Definition uint64.hpp:23
std::uint8_t byte
Represents a 8-bit unsigned integer.
Definition byte.hpp:23
enum_attribute
Specifies the enum attribute.
Definition enum_attribute.hpp:22
std::vector< std::pair< enum_t, xtd::string > > enum_collection
Represents a pair of an enum_t value and a string of an enum of type enum_t.
Definition enum_collection.hpp:24
value_t parse(const std::string &str)
Convert a string into a type.
Definition parse.hpp:34
@ flags
Enum flags attribute.
Definition enum_attribute.hpp:26
Contains xtd::icomparable interface.
Contains xtd::iequatable interface.
Contains xtd::iformatable interface.
The xtd namespace contains all fundamental classes to access Hardware, Os, System,...
Definition abstract_object.hpp:8
const_iterator begin() const
Returns an iterator to the beginning.
Definition read_only_span.hpp:183
const_iterator end() const
Returns an iterator to the end.
Definition read_only_span.hpp:213
Contains xtd::number_styles enum class.
Contains xtd::optional type.
Contains xtd::static_object class.
Contains xtd::string_comparison enum class.
Contains xtd::string_split_options enum class.
Provides the base class for enumerations.
Definition enum_object.hpp:48
bool has_flag(enum_type flag) const noexcept
Retrieves an array of the values of the constants in a specified enumeration.
Definition enum_object.hpp:90
bool equals(const object &obj) const noexcept override
Determines whether the specified object is equal to the current object.
Definition enum_object.hpp:119
int64 to_int64() const noexcept
Converts this instance to int64.
Definition enum_object.hpp:152
uint32 to_uint32() const noexcept
Converts this instance to unsigned int32.
Definition enum_object.hpp:164
xtd::string to_string(const xtd::string &format) const
Converts the value of this instance to its equivalent string representation using the specified forma...
Definition enum_object.hpp:198
uint16 to_uint16() const noexcept
Converts this instance to unsigned int16.
Definition enum_object.hpp:160
xtd::string to_string(const xtd::string &format, const globalization::culture_info &culture) const override
Converts the value of this instance to its equivalent string representation using the specified forma...
sbyte to_sbyte() const noexcept
Converts this instance to signed byte.
Definition enum_object.hpp:156
enum_t value_type
Represents the enumeration type.
Definition enum_object.hpp:55
xtd::size get_hash_code() const noexcept override
Serves as a hash function for a particular type.
Definition enum_object.hpp:136
xtd::string to_string() const noexcept override
Returns a xtd::string that represents the current object.
Definition enum_object.hpp:172
bool equals(const enum_object &value) const noexcept override
Determines whether the specified object is equal to the current object.
Definition enum_object.hpp:123
static enum_type parse(const xtd::string &str)
Converts the string to its enum_type equivalent.
Definition enum_object.hpp:227
enum_t enum_type
Represents the enumeration type.
Definition enum_object.hpp:53
xtd::byte to_byte() const noexcept
Converts this instance to byte.
Definition enum_object.hpp:140
uint64 to_uint64() const noexcept
Converts this instance to unsigned int64.
Definition enum_object.hpp:168
bool equals(attribute_t value) const noexcept
Indicates whether the current object is equal to another object with defferent type.
Definition enum_object.hpp:132
int32 to_int32() const noexcept
Converts this instance to int32.
Definition enum_object.hpp:148
enum_object() noexcept=default
Initializes a new instance of the xtd::enum_object class.
bool equals(enum_type value) const noexcept
Indicates whether the current object is equal to another object of the same type.
Definition enum_object.hpp:127
enum_type value
Gets or sets the value of the enum.
Definition enum_object.hpp:94
int16 to_int16() const noexcept
Converts this instance to int16.
Definition enum_object.hpp:144
int32 compare_to(const enum_object &value) const noexcept override
Compares the current instance with another object of the same type.
Definition enum_object.hpp:110