From dd2b534de41616654bb8f95c44ce18cf236813c1 Mon Sep 17 00:00:00 2001 From: Chris Fretz Date: Tue, 3 Mar 2020 14:20:33 -0500 Subject: [PATCH] Extended dart::string/dart::number API Added implicit conversions and operators to make them behave more like their native counterparts --- include/dart.h | 156 ++++++++++++++++++++++++++++--- include/dart/api.tcc | 18 ++-- include/dart/common.h | 7 +- include/dart/conversion_traits.h | 8 +- include/dart/heap/string.tcc | 25 ++--- include/dart/operators.tcc | 54 +++++++++++ include/dart/packet/string.tcc | 4 +- include/dart/primitive.tcc | 58 ++++++++++++ include/dart/string.tcc | 8 ++ test/operator_unit_tests.cc | 120 ++++++++++++++++++++++++ 10 files changed, 419 insertions(+), 39 deletions(-) diff --git a/include/dart.h b/include/dart.h index 946aad8..98abb9d 100644 --- a/include/dart.h +++ b/include/dart.h @@ -3333,6 +3333,24 @@ namespace dart { > basic_string() : basic_string("") {} + /** + * @brief + * Constructor can be used to directly initialize a strongly + * typed string with an initial value. + * + * @details + * Internally calls make_string on the underlying packet type + * (if implemented). + */ + template ::value + > + > + explicit basic_string(std::string const& str) : + val(value_type::make_string(str)) + {} + /** * @brief * Constructor can be used to directly initialize a strongly @@ -3351,6 +3369,40 @@ namespace dart { val(value_type::make_string(str)) {} + /** + * @brief + * Constructor can be used to directly initialize a strongly + * typed string with an initial value. + * + * @details + * Internally calls make_string on the underlying packet type + * (if implemented). + */ + template ::value + > + > + basic_string(char const* str) : + val(value_type::make_string(str)) + {} + + /** + * @brief + * Concatenation constructor. + * + * @details + * Powers dart::operator + for the purposes of string concatenation. + */ + template ::value + > + > + basic_string(shim::string_view base, shim::string_view app) : + val(value_type::make_string(base, app)) + {} + /** * @brief * Constructor allows an existing packet instance to be wrapped @@ -3511,6 +3563,23 @@ namespace dart { > basic_string& operator =(shim::string_view str) &; + /** + * @brief + * "In place" concatenation operator. + * + * @details + * Operator unfortunately does not actually work in place due to the fact + * that Dart strings are always precisely sized, not leaving room for + * additional characters like std::string. + * Concats the given suffix into a new string and assigns to itself + */ + template ::value + > + > + basic_string& operator +=(shim::string_view str); + /** * @brief * Dereference operator. @@ -3564,7 +3633,7 @@ namespace dart { * @brief * String conversion operator. */ - explicit operator shim::string_view() const noexcept; + operator shim::string_view() const noexcept; /** * @brief @@ -3835,7 +3904,7 @@ namespace dart { std::is_integral::value >* = nullptr > - explicit basic_number(Arg val) : + basic_number(Arg val) : val(value_type::make_integer(val)) {} @@ -3851,7 +3920,7 @@ namespace dart { std::is_floating_point::value >* = nullptr > - explicit basic_number(Arg val) : + basic_number(Arg val) : val(value_type::make_decimal(val)) {} @@ -4030,6 +4099,62 @@ namespace dart { > basic_number& operator =(Num val) &; + template ::value + > + > + basic_number& operator +=(Arg val) noexcept; + + template ::value + > + > + basic_number& operator -=(Arg val) noexcept; + + template ::value + > + > + basic_number& operator *=(Arg val) noexcept; + + template ::value + > + > + basic_number& operator /=(Arg val) noexcept; + + template ::value + > + > + basic_number& operator ++() noexcept; + + template ::value + > + > + basic_number& operator --() noexcept; + + template ::value + > + > + basic_number operator ++(int) noexcept; + + template ::value + > + > + basic_number operator --(int) noexcept; + /** * @brief * Dereference operator. @@ -4076,14 +4201,19 @@ namespace dart { /** * @brief * Machine type conversion operator. + * + * @details + * Operator logically exists to allow conversion into integral types, + * but is written in terms of operator T() to avoid overload ambiguity issues */ - explicit operator int64_t() const noexcept; - - /** - * @brief - * Machine type conversion operator. - */ - explicit operator double() const noexcept; + template ::value + || + std::is_floating_point::value + >* = nullptr + > + operator T() const noexcept; /** * @brief @@ -5649,7 +5779,7 @@ namespace dart { enabled > > - static basic_heap make_string(shim::string_view val); + static basic_heap make_string(shim::string_view base, shim::string_view app = ""); /** * @brief @@ -7689,7 +7819,7 @@ namespace dart { basic_heap(detail::array_tag) : data(make_shareable>()) {} - basic_heap(detail::string_tag, shim::string_view val); + basic_heap(detail::string_tag, shim::string_view base, shim::string_view); basic_heap(detail::integer_tag, int64_t val) noexcept : data(val) {} basic_heap(detail::decimal_tag, double val) noexcept : data(val) {} basic_heap(detail::boolean_tag, bool val) noexcept : data(val) {} @@ -10866,7 +10996,7 @@ namespace dart { enabled > > - static basic_packet make_string(shim::string_view val); + static basic_packet make_string(shim::string_view base, shim::string_view app = ""); /** * @brief diff --git a/include/dart/api.tcc b/include/dart/api.tcc index a64188e..3c5248f 100644 --- a/include/dart/api.tcc +++ b/include/dart/api.tcc @@ -431,14 +431,16 @@ namespace dart { } template - basic_number::operator int64_t() const noexcept { - if (is_integer()) return integer(); - else return static_cast(decimal()); - } - - template - basic_number::operator double() const noexcept { - return numeric(); + template ::value + || + std::is_floating_point::value + >* + > + basic_number::operator T() const noexcept { + if (is_integer()) return static_cast(integer()); + else return static_cast(decimal()); } template diff --git a/include/dart/common.h b/include/dart/common.h index 1216e76..351e1c6 100644 --- a/include/dart/common.h +++ b/include/dart/common.h @@ -1228,10 +1228,11 @@ namespace dart { } template