Primitive.hpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805
  1. /***************************************************************************
  2. *
  3. * Project _____ __ ____ _ _
  4. * ( _ ) /__\ (_ _)_| |_ _| |_
  5. * )(_)( /(__)\ )( (_ _)(_ _)
  6. * (_____)(__)(__)(__) |_| |_|
  7. *
  8. *
  9. * Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
  10. *
  11. * Licensed under the Apache License, Version 2.0 (the "License");
  12. * you may not use this file except in compliance with the License.
  13. * You may obtain a copy of the License at
  14. *
  15. * http://www.apache.org/licenses/LICENSE-2.0
  16. *
  17. * Unless required by applicable law or agreed to in writing, software
  18. * distributed under the License is distributed on an "AS IS" BASIS,
  19. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  20. * See the License for the specific language governing permissions and
  21. * limitations under the License.
  22. *
  23. ***************************************************************************/
  24. #ifndef oatpp_data_type_Primitive_hpp
  25. #define oatpp_data_type_Primitive_hpp
  26. #include "./Type.hpp"
  27. #include "oatpp/core/base/Countable.hpp"
  28. #include <algorithm>
  29. #include <cctype>
  30. #include <iterator>
  31. namespace oatpp { namespace data { namespace mapping { namespace type {
  32. namespace __class {
  33. class String; // FWD
  34. class Int8; // FWD
  35. class UInt8; // FWD
  36. class Int16; // FWD
  37. class UInt16; // FWD
  38. class Int32; // FWD
  39. class UInt32; // FWD
  40. class Int64; // FWD
  41. class UInt64; // FWD
  42. class Float32; // FWD
  43. class Float64; // FWD
  44. class Boolean; // FWD
  45. }
  46. /**
  47. * Mapping-enables String is &id:type::ObjectWrapper; over `std::string`;
  48. */
  49. class String : public type::ObjectWrapper<std::string, __class::String> {
  50. public:
  51. String(const std::shared_ptr<std::string>& ptr, const type::Type* const valueType);
  52. public:
  53. String() {}
  54. explicit String(v_buff_size size)
  55. : type::ObjectWrapper<std::string, __class::String>(std::make_shared<std::string>(size, '\0'))
  56. {}
  57. String(const char* data, v_buff_size size)
  58. : type::ObjectWrapper<std::string, __class::String>(std::make_shared<std::string>(data, size))
  59. {}
  60. template<typename T,
  61. typename enabled = typename std::enable_if<std::is_same<T, std::nullptr_t>::value, void>::type
  62. >
  63. String(T) {}
  64. template<typename T,
  65. typename enabled = typename std::enable_if<std::is_same<T, char>::value, void>::type
  66. >
  67. String(const T* data)
  68. : type::ObjectWrapper<std::string, __class::String>(
  69. data == nullptr ? nullptr : std::make_shared<std::string>(data)
  70. )
  71. {}
  72. template<typename T,
  73. typename enabled = typename std::enable_if<std::is_same<T, std::string>::value, void>::type
  74. >
  75. String(const T& str)
  76. : type::ObjectWrapper<std::string, __class::String>(std::make_shared<std::string>(str))
  77. {}
  78. template<typename T,
  79. typename enabled = typename std::enable_if<std::is_same<T, std::string>::value, void>::type
  80. >
  81. String(T&& str)
  82. : type::ObjectWrapper<std::string, __class::String>(
  83. std::make_shared<std::string>(std::forward<std::string>(str))
  84. )
  85. {}
  86. String(const std::shared_ptr<std::string>& ptr)
  87. : type::ObjectWrapper<std::string, __class::String>(ptr)
  88. {}
  89. String(std::shared_ptr<std::string>&& ptr)
  90. : type::ObjectWrapper<std::string, __class::String>(std::forward<std::shared_ptr<std::string>>(ptr))
  91. {}
  92. String(const String& other)
  93. : type::ObjectWrapper<std::string, __class::String>(other)
  94. {}
  95. String(String&& other)
  96. : type::ObjectWrapper<std::string, __class::String>(std::forward<String>(other))
  97. {}
  98. /**
  99. * Load data from file and store in &id:oatpp::String;.
  100. * @param filename - name of the file.
  101. * @return - &id:oatpp::String;.
  102. */
  103. static String loadFromFile(const char* filename);
  104. /**
  105. * Save content of the buffer to file.
  106. * @param filename - name of the file.
  107. */
  108. void saveToFile(const char* filename) const;
  109. const std::string& operator*() const;
  110. operator std::string() const {
  111. if (this->m_ptr == nullptr) {
  112. throw std::runtime_error("[oatpp::data::mapping::type::String::operator std::string() const]: "
  113. "Error. Null pointer.");
  114. }
  115. return this->m_ptr.operator*();
  116. }
  117. template<typename T,
  118. typename enabled = typename std::enable_if<std::is_same<T, std::nullptr_t>::value, void>::type
  119. >
  120. inline String& operator = (std::nullptr_t) {
  121. m_ptr.reset();
  122. return *this;
  123. }
  124. template<typename T,
  125. typename enabled = typename std::enable_if<std::is_same<T, char>::value, void>::type
  126. >
  127. inline String& operator = (const T* str) {
  128. if (str) {
  129. m_ptr = std::make_shared<std::string>(str);
  130. } else {
  131. m_ptr.reset();
  132. }
  133. return *this;
  134. }
  135. template<typename T,
  136. typename enabled = typename std::enable_if<std::is_same<T, std::string>::value, void>::type
  137. >
  138. inline String& operator = (const T& str) {
  139. m_ptr = std::make_shared<std::string>(str);
  140. return *this;
  141. }
  142. template<typename T,
  143. typename enabled = typename std::enable_if<std::is_same<T, std::string>::value, void>::type
  144. >
  145. inline String& operator = (T&& str) {
  146. m_ptr = std::make_shared<std::string>(std::forward<std::string>(str));
  147. return *this;
  148. }
  149. inline String& operator = (const String& other){
  150. m_ptr = other.m_ptr;
  151. return *this;
  152. }
  153. inline String& operator = (String&& other) noexcept {
  154. m_ptr = std::move(other.m_ptr);
  155. return *this;
  156. }
  157. /**
  158. * Case insensitive compare (ASCII only).
  159. * @param other
  160. * @return
  161. */
  162. bool equalsCI_ASCII(const std::string& other);
  163. /**
  164. * Case insensitive compare (ASCII only).
  165. * @param other
  166. * @return
  167. */
  168. bool equalsCI_ASCII(const String& other);
  169. /**
  170. * Case insensitive compare (ASCII only).
  171. * @param other
  172. * @return
  173. */
  174. bool equalsCI_ASCII(const char* str);
  175. /**
  176. * Get underlying value.
  177. * @param defaultValue - value to return in case stored value is `nullptr`.
  178. * @return - value or `defaultValue` if stored value is `nullptr`.
  179. */
  180. std::string getValue(const std::string& defaultValue) const;
  181. template<typename T,
  182. typename enabled = typename std::enable_if<std::is_same<T, std::nullptr_t>::value, void>::type
  183. >
  184. inline bool operator == (T) const {
  185. return m_ptr.get() == nullptr;
  186. }
  187. template<typename T,
  188. typename enabled = typename std::enable_if<std::is_same<T, std::nullptr_t>::value, void>::type
  189. >
  190. inline bool operator != (T) const {
  191. return m_ptr.get() != nullptr;
  192. }
  193. template<typename T,
  194. typename enabled = typename std::enable_if<std::is_same<T, char>::value, void>::type
  195. >
  196. inline bool operator == (const T* str) const {
  197. if(!m_ptr) return str == nullptr;
  198. if(str == nullptr) return false;
  199. return *m_ptr == str;
  200. }
  201. template<typename T,
  202. typename enabled = typename std::enable_if<std::is_same<T, char>::value, void>::type
  203. >
  204. inline bool operator != (const T* str) const {
  205. return !operator == (str);
  206. }
  207. template<typename T,
  208. typename enabled = typename std::enable_if<std::is_same<T, std::string>::value, void>::type
  209. >
  210. inline bool operator == (const T& str) const {
  211. if(!m_ptr) return false;
  212. return *m_ptr == str;
  213. }
  214. template<typename T,
  215. typename enabled = typename std::enable_if<std::is_same<T, std::string>::value, void>::type
  216. >
  217. inline bool operator != (const T& str) const {
  218. return !operator == (str);
  219. }
  220. inline bool operator == (const String &other) const {
  221. if(!m_ptr) return !other.m_ptr;
  222. if(!other.m_ptr) return false;
  223. return *m_ptr == *other.m_ptr;
  224. }
  225. inline bool operator != (const String &other) const {
  226. return !operator == (other);
  227. }
  228. };
  229. String operator + (const char* a, const String& b);
  230. String operator + (const String& a, const char* b);
  231. String operator + (const String& a, const String& b);
  232. /**
  233. * Template for primitive mapping-enabled types.
  234. * @tparam TValueType - type of the value ex.: v_int64.
  235. * @tparam Clazz - Class holding static class information.
  236. */
  237. template<typename TValueType, class Clazz>
  238. class Primitive : public type::ObjectWrapper<TValueType, Clazz> {
  239. public:
  240. typedef TValueType UnderlyingType;
  241. public:
  242. OATPP_DEFINE_OBJECT_WRAPPER_DEFAULTS(Primitive, TValueType, Clazz)
  243. Primitive(TValueType value)
  244. : type::ObjectWrapper<TValueType, Clazz>(std::make_shared<TValueType>(value))
  245. {}
  246. Primitive& operator = (TValueType value) {
  247. this->m_ptr = std::make_shared<TValueType>(value);
  248. return *this;
  249. }
  250. TValueType operator*() const {
  251. return this->m_ptr.operator*();
  252. }
  253. template<typename T,
  254. typename enabled = typename std::enable_if<std::is_same<T, std::nullptr_t>::value, void>::type
  255. >
  256. inline bool operator == (T){
  257. return this->m_ptr.get() == nullptr;
  258. }
  259. template<typename T,
  260. typename enabled = typename std::enable_if<std::is_same<T, std::nullptr_t>::value, void>::type
  261. >
  262. inline bool operator != (T){
  263. return this->m_ptr.get() != nullptr;
  264. }
  265. template<typename T,
  266. typename enabled = typename std::enable_if<std::is_same<T, TValueType>::value, void>::type
  267. >
  268. inline bool operator == (T value) const {
  269. if(!this->m_ptr) return false;
  270. return *this->m_ptr == value;
  271. }
  272. template<typename T,
  273. typename enabled = typename std::enable_if<std::is_same<T, TValueType>::value, void>::type
  274. >
  275. inline bool operator != (T value) const {
  276. if(!this->m_ptr) return true;
  277. return *this->m_ptr != value;
  278. }
  279. template<typename T,
  280. typename enabled = typename std::enable_if<std::is_same<T, Primitive>::value, void>::type
  281. >
  282. inline bool operator == (const T &other) const {
  283. if(this->m_ptr.get() == other.m_ptr.get()) return true;
  284. if(!this->m_ptr || !other.m_ptr) return false;
  285. return *this->m_ptr == *other.m_ptr;
  286. }
  287. template<typename T,
  288. typename enabled = typename std::enable_if<std::is_same<T, Primitive>::value, void>::type
  289. >
  290. inline bool operator != (const T &other) const {
  291. return !operator == (other);
  292. }
  293. inline operator TValueType() const {
  294. return *this->m_ptr;
  295. }
  296. TValueType getValue(const TValueType& defaultValue) const {
  297. if(this->m_ptr) {
  298. return *this->m_ptr;
  299. }
  300. return defaultValue;
  301. }
  302. };
  303. /**
  304. * ObjectWrapper for Boolean.
  305. */
  306. class Boolean : public type::ObjectWrapper<bool, __class::Boolean> {
  307. public:
  308. typedef bool UnderlyingType;
  309. public:
  310. OATPP_DEFINE_OBJECT_WRAPPER_DEFAULTS(Boolean, bool, __class::Boolean)
  311. Boolean(bool value)
  312. : type::ObjectWrapper<bool, __class::Boolean>(std::make_shared<bool>(value))
  313. {}
  314. Boolean& operator = (bool value) {
  315. this->m_ptr = std::make_shared<bool>(value);
  316. return *this;
  317. }
  318. inline bool operator*() const {
  319. return this->m_ptr.operator*();
  320. }
  321. template<typename T,
  322. typename enabled = typename std::enable_if<std::is_same<T, std::nullptr_t>::value, void>::type
  323. >
  324. inline bool operator == (T){
  325. return m_ptr.get() == nullptr;
  326. }
  327. template<typename T,
  328. typename enabled = typename std::enable_if<std::is_same<T, std::nullptr_t>::value, void>::type
  329. >
  330. inline bool operator != (T){
  331. return m_ptr.get() != nullptr;
  332. }
  333. template<typename T,
  334. typename enabled = typename std::enable_if<std::is_same<T, bool>::value, void>::type
  335. >
  336. inline bool operator == (T value) const {
  337. if(!this->m_ptr) return false;
  338. return *this->m_ptr == value;
  339. }
  340. template<typename T,
  341. typename enabled = typename std::enable_if<std::is_same<T, bool>::value, void>::type
  342. >
  343. inline bool operator != (T value) const {
  344. if(!this->m_ptr) return true;
  345. return *this->m_ptr != value;
  346. }
  347. inline bool operator == (const Boolean &other) const {
  348. if(this->m_ptr.get() == other.m_ptr.get()) return true;
  349. if(!this->m_ptr || !other.m_ptr) return false;
  350. return *this->m_ptr == *other.m_ptr;
  351. }
  352. inline bool operator != (const Boolean &other) const {
  353. return !operator == (other);
  354. }
  355. inline operator bool() const {
  356. if(this->m_ptr) {
  357. return *(this->m_ptr);
  358. }
  359. return false;
  360. }
  361. bool getValue(bool defaultValue) const {
  362. if(this->m_ptr) {
  363. return *this->m_ptr;
  364. }
  365. return defaultValue;
  366. }
  367. };
  368. /**
  369. * Int8 is an ObjectWrapper over `v_int8` and __class::Int8.
  370. */
  371. typedef Primitive<v_int8, __class::Int8> Int8;
  372. /**
  373. * UInt8 is an ObjectWrapper over `v_uint8` and __class::UInt8.
  374. */
  375. typedef Primitive<v_uint8, __class::UInt8> UInt8;
  376. /**
  377. * Int16 is an ObjectWrapper over `v_int16` and __class::Int16.
  378. */
  379. typedef Primitive<v_int16, __class::Int16> Int16;
  380. /**
  381. * UInt16 is an ObjectWrapper over `v_uint16` and __class::UInt16.
  382. */
  383. typedef Primitive<v_uint16, __class::UInt16> UInt16;
  384. /**
  385. * Int32 is an ObjectWrapper over `v_int32` and __class::Int32.
  386. */
  387. typedef Primitive<v_int32, __class::Int32> Int32;
  388. /**
  389. * UInt32 is an ObjectWrapper over `v_uint32` and __class::UInt32.
  390. */
  391. typedef Primitive<v_uint32, __class::UInt32> UInt32;
  392. /**
  393. * Int64 is an ObjectWrapper over `v_int64` and __class::Int64.
  394. */
  395. typedef Primitive<v_int64, __class::Int64> Int64;
  396. /**
  397. * UInt64 is an ObjectWrapper over `v_uint64` and __class::UInt64.
  398. */
  399. typedef Primitive<v_uint64, __class::UInt64> UInt64;
  400. /**
  401. * Float32 is an ObjectWrapper over `v_float32` and __class::Float32.
  402. */
  403. typedef Primitive<v_float32, __class::Float32> Float32;
  404. /**
  405. * Float64 is an ObjectWrapper over `v_float64` and __class::Float64.
  406. */
  407. typedef Primitive<v_float64, __class::Float64> Float64;
  408. template<>
  409. struct ObjectWrapperByUnderlyingType <v_int8> {
  410. typedef Int8 ObjectWrapper;
  411. };
  412. template<>
  413. struct ObjectWrapperByUnderlyingType <v_uint8> {
  414. typedef UInt8 ObjectWrapper;
  415. };
  416. template<>
  417. struct ObjectWrapperByUnderlyingType <v_int16> {
  418. typedef Int16 ObjectWrapper;
  419. };
  420. template<>
  421. struct ObjectWrapperByUnderlyingType <v_uint16> {
  422. typedef UInt16 ObjectWrapper;
  423. };
  424. template<>
  425. struct ObjectWrapperByUnderlyingType <v_int32> {
  426. typedef Int32 ObjectWrapper;
  427. };
  428. template<>
  429. struct ObjectWrapperByUnderlyingType <v_uint32> {
  430. typedef UInt32 ObjectWrapper;
  431. };
  432. template<>
  433. struct ObjectWrapperByUnderlyingType <v_int64> {
  434. typedef Int64 ObjectWrapper;
  435. };
  436. template<>
  437. struct ObjectWrapperByUnderlyingType <v_uint64> {
  438. typedef UInt64 ObjectWrapper;
  439. };
  440. template<>
  441. struct ObjectWrapperByUnderlyingType <bool> {
  442. typedef Boolean ObjectWrapper;
  443. };
  444. namespace __class {
  445. class String {
  446. public:
  447. static const ClassId CLASS_ID;
  448. static Type* getType();
  449. };
  450. class Int8 {
  451. public:
  452. static const ClassId CLASS_ID;
  453. static Type* getType();
  454. };
  455. class UInt8 {
  456. public:
  457. static const ClassId CLASS_ID;
  458. static Type* getType();
  459. };
  460. class Int16 {
  461. public:
  462. static const ClassId CLASS_ID;
  463. static Type* getType();
  464. };
  465. class UInt16 {
  466. public:
  467. static const ClassId CLASS_ID;
  468. static Type* getType();
  469. };
  470. class Int32 {
  471. public:
  472. static const ClassId CLASS_ID;
  473. static Type* getType();
  474. };
  475. class UInt32 {
  476. public:
  477. static const ClassId CLASS_ID;
  478. static Type* getType();
  479. };
  480. class Int64 {
  481. public:
  482. static const ClassId CLASS_ID;
  483. static Type* getType();
  484. };
  485. class UInt64 {
  486. public:
  487. static const ClassId CLASS_ID;
  488. static Type* getType();
  489. };
  490. class Float32 {
  491. public:
  492. static const ClassId CLASS_ID;
  493. static Type* getType();
  494. };
  495. class Float64 {
  496. public:
  497. static const ClassId CLASS_ID;
  498. static Type* getType();
  499. };
  500. class Boolean {
  501. public:
  502. static const ClassId CLASS_ID;
  503. static Type* getType();
  504. };
  505. }
  506. }}}}
  507. namespace std {
  508. template<>
  509. struct hash<oatpp::data::mapping::type::String> {
  510. typedef oatpp::data::mapping::type::String argument_type;
  511. typedef v_uint64 result_type;
  512. result_type operator()(argument_type const& s) const noexcept {
  513. if(s.get() == nullptr) return 0;
  514. return hash<std::string> {} (*s);
  515. }
  516. };
  517. template<>
  518. struct hash<oatpp::data::mapping::type::Boolean> {
  519. typedef oatpp::data::mapping::type::Boolean argument_type;
  520. typedef v_uint64 result_type;
  521. result_type operator()(argument_type const& v) const noexcept {
  522. if(v.get() == nullptr) return 2;
  523. return result_type(*v);
  524. }
  525. };
  526. template<>
  527. struct hash<oatpp::data::mapping::type::Int8> {
  528. typedef oatpp::data::mapping::type::Int8 argument_type;
  529. typedef v_uint64 result_type;
  530. result_type operator()(argument_type const& v) const noexcept {
  531. if(v.get() == nullptr) return 0;
  532. return (result_type) *v;
  533. }
  534. };
  535. template<>
  536. struct hash<oatpp::data::mapping::type::UInt8> {
  537. typedef oatpp::data::mapping::type::UInt8 argument_type;
  538. typedef v_uint64 result_type;
  539. result_type operator()(argument_type const& v) const noexcept {
  540. if(v.get() == nullptr) return 0;
  541. return (result_type) *v;
  542. }
  543. };
  544. template<>
  545. struct hash<oatpp::data::mapping::type::Int16> {
  546. typedef oatpp::data::mapping::type::Int16 argument_type;
  547. typedef v_uint64 result_type;
  548. result_type operator()(argument_type const& v) const noexcept {
  549. if(v.get() == nullptr) return 0;
  550. return (result_type) *v;
  551. }
  552. };
  553. template<>
  554. struct hash<oatpp::data::mapping::type::UInt16> {
  555. typedef oatpp::data::mapping::type::UInt16 argument_type;
  556. typedef v_uint64 result_type;
  557. result_type operator()(argument_type const& v) const noexcept {
  558. if(v.get() == nullptr) return 0;
  559. return (result_type) *v;
  560. }
  561. };
  562. template<>
  563. struct hash<oatpp::data::mapping::type::Int32> {
  564. typedef oatpp::data::mapping::type::Int32 argument_type;
  565. typedef v_uint64 result_type;
  566. result_type operator()(argument_type const& v) const noexcept {
  567. if(v.get() == nullptr) return 0;
  568. return (result_type) *v;
  569. }
  570. };
  571. template<>
  572. struct hash<oatpp::data::mapping::type::UInt32> {
  573. typedef oatpp::data::mapping::type::UInt32 argument_type;
  574. typedef v_uint64 result_type;
  575. result_type operator()(argument_type const& v) const noexcept {
  576. if(v.get() == nullptr) return 0;
  577. return (result_type) *v;
  578. }
  579. };
  580. template<>
  581. struct hash<oatpp::data::mapping::type::Int64> {
  582. typedef oatpp::data::mapping::type::Int64 argument_type;
  583. typedef v_uint64 result_type;
  584. result_type operator()(argument_type const& v) const noexcept {
  585. if(v.get() == nullptr) return 0;
  586. return (result_type) *v;
  587. }
  588. };
  589. template<>
  590. struct hash<oatpp::data::mapping::type::UInt64> {
  591. typedef oatpp::data::mapping::type::UInt64 argument_type;
  592. typedef v_uint64 result_type;
  593. result_type operator()(argument_type const& v) const noexcept {
  594. if(v.get() == nullptr) return 0;
  595. return (result_type) *v;
  596. }
  597. };
  598. template<>
  599. struct hash<oatpp::data::mapping::type::Float32> {
  600. typedef oatpp::data::mapping::type::Float32 argument_type;
  601. typedef v_uint64 result_type;
  602. result_type operator()(argument_type const& v) const noexcept {
  603. if(v.get() == nullptr) return 0;
  604. return *((v_uint32*) v.get());
  605. }
  606. };
  607. template<>
  608. struct hash<oatpp::data::mapping::type::Float64> {
  609. typedef oatpp::data::mapping::type::Float64 argument_type;
  610. typedef v_uint64 result_type;
  611. result_type operator()(argument_type const& v) const noexcept {
  612. if(v.get() == nullptr) return 0;
  613. return *((result_type*) v.get());
  614. }
  615. };
  616. }
  617. #endif /* oatpp_base_Countable_PrimitiveDataTypes_hpp */