General Purpose library for Freestanding C++ and POSIX systems
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

99 linhas
1.5 KiB

  1. #pragma once
  2. #include <type_traits>
  3. #include "gp_config.hpp"
  4. #include "gp/exception.hpp"
  5. #include "gp/memory.hpp"
  6. namespace gp{
  7. struct nullopt_t{};
  8. constexpr nullopt_t nullopt;
  9. template<typename T, bool B = std::is_final<T>::value || std::is_fundamental<T>::value>
  10. class optional;
  11. template<typename T>
  12. class optional<T,true>{
  13. bool ready = false;
  14. char buffer[sizeof(T)];
  15. public:
  16. constexpr optional()
  17. : ready{false}
  18. {}
  19. constexpr optional(nullopt_t)
  20. : ready{false}
  21. {}
  22. constexpr optional(T& value)
  23. : ready{true}
  24. {
  25. new(buffer) T(value);
  26. }
  27. constexpr optional(T&& value)
  28. : ready{true}
  29. {
  30. new(buffer) T(std::move(value));
  31. }
  32. constexpr bool has_value()
  33. {
  34. return ready;
  35. }
  36. constexpr T& value()
  37. {
  38. if constexpr (gp_config::has_exceptions)
  39. {
  40. if(!ready)
  41. {
  42. throw bad_optional{};
  43. }
  44. }
  45. return *reinterpret_cast<T*>(buffer);
  46. }
  47. };
  48. template<typename T>
  49. class optional<T,false>{
  50. bool ready = false;
  51. void* ptr;
  52. public:
  53. constexpr optional()
  54. : ready{false}
  55. {}
  56. constexpr optional(nullopt_t)
  57. : ready{false}
  58. {}
  59. constexpr optional(T& value)
  60. : ready{true}
  61. {
  62. ptr = (void*)new T(value);
  63. }
  64. constexpr optional(T&& value)
  65. : ready{true}
  66. {
  67. ptr = (void*)new T(std::move(value));
  68. }
  69. constexpr bool has_value()
  70. {
  71. return ready;
  72. }
  73. constexpr T& value()
  74. {
  75. if constexpr (gp_config::has_exceptions)
  76. {
  77. if(!ready)
  78. {
  79. throw bad_optional{};
  80. }
  81. }
  82. return *reinterpret_cast<T*>(ptr);
  83. }
  84. };
  85. }