diff --git a/.gitignore b/.gitignore
index f8f1c27..922973f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
tags
compile_commands.json
+.clangd
diff --git a/include/duckhandy/int_to_string_ary.hpp b/include/duckhandy/int_to_string_ary.hpp
deleted file mode 100644
index 98ae0c0..0000000
--- a/include/duckhandy/int_to_string_ary.hpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright 2016-2018 Michele Santullo
- * This file is part of "duckhandy".
- *
- * "duckhandy" is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * "duckhandy" is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with "duckhandy". If not, see .
- */
-
-#ifndef idB123739E9F8846899541DB26BEA86386
-#define idB123739E9F8846899541DB26BEA86386
-
-#include "lexical_cast.hpp"
-
-namespace dhandy {
- namespace customize {
- template
- struct array_to_t> {
- static MaxSizedArray make (MaxSizedArray&& parIn) {
- return parIn;
- }
- };
- } //namespace customize
-
- template class Tag=tags::dec, typename F=void>
- inline auto int_to_string_ary (const F& parFrom) -> MaxSizedArray::count_digits_bt(sprout::numeric_limits::max())> {
- return dhandy::lexical_cast::count_digits_bt(sprout::numeric_limits::max())>, Tag, F>(parFrom);
- }
-} //namespace dhandy
-
-#endif
diff --git a/include/duckhandy/lexical_cast.hpp b/include/duckhandy/lexical_cast.hpp
deleted file mode 100644
index af855fe..0000000
--- a/include/duckhandy/lexical_cast.hpp
+++ /dev/null
@@ -1,316 +0,0 @@
-/* Copyright 2016-2018 Michele Santullo
- * This file is part of "duckhandy".
- *
- * "duckhandy" is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * "duckhandy" is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with "duckhandy". If not, see .
- */
-
-#ifndef id942A6B5AB2AF443C82D4321775BFC9E8
-#define id942A6B5AB2AF443C82D4321775BFC9E8
-
-#include "compatibility.h"
-#include "sequence_bt.hpp"
-#include "MaxSizedArray.hpp"
-#include "has_method.hpp"
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-namespace dhandy {
- namespace customize {
- template
- struct index_to_char;
-
- template
- struct char_to_int;
-
- template
- struct array_to_t;
- } //namespace customize
-
- namespace implem {
- template
- typename std::make_unsigned::type abs ( T parValue ) a_pure;
-
- template int count_leading_zeroes ( typename std::enable_if::is_signed, T>::type parValue ) a_always_inline;
- template int count_leading_zeroes ( typename std::enable_if::is_signed, T>::type parValue ) a_always_inline;
- int count_leading_zeroes_overload ( unsigned char parValue ) a_always_inline;
- int count_leading_zeroes_overload ( unsigned short int parValue ) a_always_inline;
- int count_leading_zeroes_overload ( unsigned int parValue ) a_always_inline;
- int count_leading_zeroes_overload ( unsigned long parValue ) a_always_inline;
- int count_leading_zeroes_overload ( unsigned long long parValue ) a_always_inline;
-
- template
- struct power {
- enum { value = Base * power::value };
- };
- template
- struct power {
- enum { value = 1 };
- };
-
- template ::is_signed>
- struct is_negative;
- template
- struct is_negative {
- static int check (T parValue) { return (parValue < 0 ? 1 : 0); }
- };
- template
- struct is_negative {
- static constexpr int check (T) { return 0; }
- };
-
-
- template class Tag, typename F, typename C>
- inline auto int_to_string (const F parFrom) -> MaxSizedArray::count_digits_bt(sprout::numeric_limits::max())> {
- using ArrayRetType = MaxSizedArray::count_digits_bt(sprout::numeric_limits::max())>;
-
- ArrayRetType retval;
- F div = 1;
- constexpr const std::size_t charset_offs = (Tag::lower_case ? Tag::base + 1 : 1);
- const auto sign_length = (is_negative::check(parFrom) and Tag::sign_allowed ? 1 : 0);
- for (std::size_t z = 0; z < Tag::count_digits(parFrom) - sign_length; ++z) {
- const uint8_t idx = static_cast(((parFrom / div) % Tag::base) + charset_offs);
- retval.push_back(dhandy::customize::index_to_char::make(idx));
- div *= Tag::base;
- }
- if (sign_length)
- retval.push_back(dhandy::customize::index_to_char::make(0));
- std::reverse(retval.begin(), retval.end());
- return retval;
- };
-
- template class Tag, typename T, typename F>
- inline T string_to_int (const F& parFrom) {
- T retval(0);
- T mul(1);
- const auto sgn = dhandy::customize::char_to_int::sgn(parFrom);
- for (auto it = std::rbegin(parFrom), itEND = std::rend(parFrom); it + (sgn < 0 ? 1 : 0) != itEND; ++it) {
- auto chara = *it;
- retval += dhandy::customize::char_to_int::make(chara) * mul;
- mul *= Tag::base;
- }
- return retval * sgn;
- };
-
- template
- struct hex {
- enum {
- base = 16,
- sign_allowed = 0,
- lower_case = (LowerCase ? 1 : 0)
- };
-
- static std::size_t count_digits ( T parValue ) a_pure;
- static constexpr std::size_t count_digits_bt (T parNum) {
- return (parNum == 0 ? 0 : static_cast(sprout::log10(sprout::abs(static_cast(parNum))) / sprout::log10(static_cast(base)))) + 1;
- }
- };
-
- define_has_typedef(char_type, CharType);
- define_has_typedef(value_type, ValueType);
-
- template struct get_char_type;
- template struct get_char_type::value>::type> {
- typedef typename T::char_type value_type;
- };
- template struct get_char_type::value && !HasCharTypeTypedef::value>::type> {
- typedef typename T::value_type value_type;
- };
- } //namespace implem
-
- namespace tags {
- template
- struct dec {
- enum {
- base = 10,
- sign_allowed = 1,
- lower_case = 0
- };
-
- template
- static std::size_t count_digits_implem (T parValue, dhandy::bt::index_seq, dhandy::bt::index_seq) a_pure;
-
- static std::size_t count_digits (T parValue) a_pure;
-
- static constexpr std::size_t count_digits_bt (T parNum) {
- return (parNum == 0 ? 0 : static_cast(sprout::log10(sprout::abs(static_cast(parNum))))) + 1 + (sprout::numeric_limits::is_signed ? 1 : 0);
- }
- };
-
- template
- using hex = dhandy::implem::hex;
- template
- using hexl = dhandy::implem::hex;
-
- template
- struct bin {
- enum {
- base = 2,
- sign_allowed = 0,
- lower_case = 0
- };
-
- static std::size_t count_digits ( T parValue ) a_pure;
- static constexpr std::size_t count_digits_bt (T parNum) {
- return (parNum == 0 ? 0 : static_cast(sprout::log2(sprout::abs(static_cast(parNum))))) + 1;
- }
- };
-
- //See: http://stackoverflow.com/questions/9721042/count-number-of-digits-which-method-is-most-efficient#9721113
- template
- template
- std::size_t dec::count_digits_implem (T parValue, dhandy::bt::index_seq, dhandy::bt::index_seq) {
- static_assert(sizeof...(Digits) == CHAR_BIT * sizeof(T) + 1, "Too many values for Digits");
- typedef typename std::make_unsigned::type UT;
- static constexpr UT powers[] = { 0, static_cast(dhandy::implem::power<10, Powers + 1>::value)... };
- //the maxdigits table is [len(str(pow(2,b))) for b in range(0,MAX_BITS)]
- static constexpr std::size_t maxdigits[] = { static_cast(static_cast(Digits) / sprout::log2(10.0)) + 1 ... };
- static_assert(maxdigits[sizeof(maxdigits) / sizeof(maxdigits[0]) - 1] <= sprout::numeric_limits::max(), "Last item in maxdigits overflows T");
- const auto bits = sizeof(parValue) * CHAR_BIT - dhandy::implem::count_leading_zeroes(dhandy::implem::abs(parValue));
- static_assert(std::is_same::value, "Unexpected type");
- assert(bits < sizeof(maxdigits) / sizeof(maxdigits[0]));
- return (dhandy::implem::abs(parValue) < powers[maxdigits[bits] - 1] ? maxdigits[bits] - 1 : maxdigits[bits]) + dhandy::implem::is_negative::check(parValue);
- }
-
- template
- std::size_t dec::count_digits (T parValue) {
- return count_digits_implem(
- parValue,
- dhandy::bt::index_range<0, count_digits_bt(sprout::numeric_limits::max()) - (sprout::numeric_limits::is_signed ? 1 : 0) - 1>(),
- dhandy::bt::index_range<0, CHAR_BIT * sizeof(T) + 1>()
- );
- }
-
- template
- std::size_t bin::count_digits (T parValue) {
- return std::max((sizeof(parValue) * CHAR_BIT - dhandy::implem::count_leading_zeroes(parValue)), 1);
- }
- } //namespace tags
-
- namespace implem {
- template class Tag>
- struct lexical_cast {
- template
- static T convert ( const typename std::enable_if::value, F>::type& parFrom ) {
- auto indices = int_to_string::value_type>(parFrom);
- return dhandy::customize::array_to_t::make(std::move(indices));
- }
-
- template
- static typename std::enable_if::value, T>::type convert ( const F& parFrom ) {
- return string_to_int(parFrom);
- }
- };
-
- template
- inline int count_leading_zeroes (typename std::enable_if::is_signed, T>::type parValue) {
- return count_leading_zeroes(dhandy::implem::abs(parValue));
- }
-
- template
- inline int count_leading_zeroes (typename std::enable_if::is_signed, T>::type parValue) {
- return count_leading_zeroes_overload(parValue) + sizeof(T) * CHAR_BIT;
- }
-
- inline int count_leading_zeroes_overload (unsigned char parValue) {
- return __builtin_clz(parValue) - sizeof(unsigned int) * CHAR_BIT;
- }
- inline int count_leading_zeroes_overload (unsigned short int parValue) {
- return __builtin_clz(parValue) - sizeof(unsigned int) * CHAR_BIT;
- }
- inline int count_leading_zeroes_overload (unsigned int parValue) {
- return __builtin_clz(parValue) - sizeof(unsigned int) * CHAR_BIT;
- }
- inline int count_leading_zeroes_overload (unsigned long parValue) {
- return __builtin_clzl(parValue) - sizeof(unsigned long) * CHAR_BIT;
- }
- inline int count_leading_zeroes_overload (unsigned long long parValue) {
- return __builtin_clzll(parValue) - sizeof(unsigned long long) * CHAR_BIT;
- }
-
- //See: http://stackoverflow.com/questions/16101062/why-does-stdabs-return-signed-types
- template
- typename std::make_unsigned::type abs (T parValue) {
- //We need to cast before negating x to avoid the overflow.
- return (parValue < 0 ? -static_cast::type>(parValue) : parValue);
- }
-
- template
- std::size_t hex::count_digits (T parValue) {
- return std::max(((sizeof(parValue) * CHAR_BIT - dhandy::implem::count_leading_zeroes(parValue)) + (CHAR_BIT / 2 - 1)) / (CHAR_BIT / 2), 1);
- }
- } //namespace implem
-
- template class Tag=tags::dec, typename F=void>
- inline T lexical_cast (const F& parFrom) {
- return dhandy::implem::lexical_cast::template convert(parFrom);
- }
-
- namespace customize {
- template<>
- struct index_to_char {
- static char make (uint8_t parIndex) {
- static const char symbols[] = {
- '-',
- '0', '1', '2', '3', '4', '5',
- '6', '7', '8', '9', 'A', 'B',
- 'C', 'D', 'E', 'F',
- '0', '1', '2', '3', '4', '5',
- '6', '7', '8', '9', 'a', 'b',
- 'c', 'd', 'e', 'f'
- };
- return symbols[parIndex];
- }
- };
-
- template
- struct char_to_int {
- static T make (char parChar) {
- if (parChar >= '0' and parChar <= '9')
- return parChar - '0';
- else if (parChar >= 'a' and parChar <= 'f')
- return 10 + parChar - 'a';
- else if (parChar >= 'A' and parChar <= 'F')
- return 10 + parChar - 'A';
- else if (parChar == '-')
- return 0;
- return 0;
- }
-
- template
- static T sgn (const Container& parString) {
- return static_cast(sprout::numeric_limits::is_signed and std::begin(parString) != std::end(parString) and *std::begin(parString) == '-' ? -1 : 1);
- }
- };
-
- template
- struct array_to_t {
- static std::string make (MaxSizedArray&& parIn) {
- return std::string(parIn.begin(), parIn.end());
- }
- };
- } //namespace customize
-} //namespace dhandy
-#endif
diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt
index c13f53e..eaae1f8 100644
--- a/test/unit/CMakeLists.txt
+++ b/test/unit/CMakeLists.txt
@@ -2,7 +2,6 @@ project(dhandy_unit_test CXX)
add_executable(${PROJECT_NAME}
main.cpp
- lexical_cast_test.cpp
endianness_test.cpp
int_conv_test.cpp
reversed_sized_array_test.cpp
diff --git a/test/unit/lexical_cast_test.cpp b/test/unit/lexical_cast_test.cpp
deleted file mode 100644
index 839e1c9..0000000
--- a/test/unit/lexical_cast_test.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-/* Copyright 2016-2018 Michele Santullo
- * This file is part of "duckhandy".
- *
- * "duckhandy" is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * "duckhandy" is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with "duckhandy". If not, see .
- */
-
-#include "catch2/catch.hpp"
-#include "duckhandy/lexical_cast.hpp"
-#include "duckhandy/int_to_string_ary.hpp"
-#include
-#include
-#include
-#include
-
-template (C==E)>
-struct CountDigitsDebugger { static constexpr const bool value = true; };
-template
-struct CountDigitsDebugger {};
-
-TEST_CASE ("Check string to int conversions", "[s2i][lexical_cast]") {
- using dhandy::lexical_cast;
- using dhandy::tags::dec;
- using dhandy::tags::hex;
- using dhandy::tags::bin;
-
- static_assert(CountDigitsDebugger::count_digits_bt(0), 1>::value, "Wrong digits count");
- static_assert(CountDigitsDebugger::count_digits_bt(1), 1>::value, "Wrong digits count");
- static_assert(CountDigitsDebugger::count_digits_bt(2), 2>::value, "Wrong digits count");
- static_assert(CountDigitsDebugger::count_digits_bt(3), 2>::value, "Wrong digits count");
- static_assert(CountDigitsDebugger::count_digits_bt(4), 3>::value, "Wrong digits count");
- static_assert(CountDigitsDebugger::count_digits_bt(5), 3>::value, "Wrong digits count");
- static_assert(CountDigitsDebugger::count_digits_bt(6), 3>::value, "Wrong digits count");
- static_assert(CountDigitsDebugger::count_digits_bt(7), 3>::value, "Wrong digits count");
- static_assert(CountDigitsDebugger::count_digits_bt(8), 4>::value, "Wrong digits count");
- static_assert(CountDigitsDebugger::count_digits_bt(9), 4>::value, "Wrong digits count");
- static_assert(CountDigitsDebugger::count_digits_bt(255), 8>::value, "Wrong digits count");
- static_assert(CountDigitsDebugger::count_digits_bt(256), 9>::value, "Wrong digits count");
- static_assert(CountDigitsDebugger::count_digits_bt(255), 8>::value, "Wrong digits count");
- static_assert(CountDigitsDebugger::count_digits_bt(256), 9>::value, "Wrong digits count");
- static_assert(CountDigitsDebugger::count_digits_bt(255), 8>::value, "Wrong digits count");
- static_assert(CountDigitsDebugger::count_digits_bt(256), 9>::value, "Wrong digits count");
- static_assert(CountDigitsDebugger::count_digits_bt(255), 8>::value, "Wrong digits count");
- static_assert(CountDigitsDebugger::count_digits_bt(255), 8>::value, "Wrong digits count");
- static_assert(CountDigitsDebugger::count_digits_bt(-1), 2>::value, "Wrong digits count");
- static_assert(CountDigitsDebugger::count_digits_bt(-2), 2>::value, "Wrong digits count");
- static_assert(CountDigitsDebugger::count_digits_bt(-10), 3>::value, "Wrong digits count");
- static_assert(CountDigitsDebugger::count_digits_bt(-99), 3>::value, "Wrong digits count");
- static_assert(static_cast(sprout::log10(sprout::abs(-10000000.0))) == 7, "Wrong log10");
- static_assert(CountDigitsDebugger::count_digits_bt(-10000000), 9>::value, "Wrong digits count");
- static_assert(CountDigitsDebugger::count_digits_bt(-123456789), 10>::value, "Wrong digits count");
- static_assert(CountDigitsDebugger::count_digits_bt(INT_MAX), 11>::value, "Wrong digits count");
- static_assert(CountDigitsDebugger::count_digits_bt(INT_MIN), 11>::value, "Wrong digits count");
-
- CHECK(lexical_cast(std::string("0")) == 0);
- CHECK(lexical_cast(std::string("1")) == 1);
- CHECK(lexical_cast(std::string("9")) == 9);
- CHECK(lexical_cast(std::string("10")) == 10);
- CHECK(lexical_cast(std::string("11")) == 11);
- CHECK(lexical_cast(std::string("99")) == 99);
- CHECK(lexical_cast(std::string("512")) == 512);
- CHECK(lexical_cast(std::string("513")) == 513);
- CHECK(lexical_cast(std::string("15000")) == 15000);
-
- CHECK(lexical_cast(std::string("-1")) == -1);
- CHECK(lexical_cast(std::string("-2")) == -2);
- CHECK(lexical_cast(std::string("-10")) == -10);
- CHECK(lexical_cast(std::string("-100000")) == -100000);
-}
-
-TEST_CASE ("Check int to string conversions", "[i2s][lexical_cast]") {
- using std::string;
- using dhandy::lexical_cast;
- using dhandy::tags::bin;
- using dhandy::int_to_string_ary;
-
- CHECK(lexical_cast(1) == "1");
- CHECK(lexical_cast(static_cast(0xFFFF)) == "65535");
-
- CHECK(lexical_cast(static_cast(0xFFFF)) == "65535");
- CHECK((lexical_cast(static_cast(0xFFFF)) == "1111111111111111"));
- CHECK((lexical_cast(static_cast(0x7FFF)) == "111111111111111"));
- CHECK((lexical_cast(static_cast(0x0)) == "0"));
- CHECK((lexical_cast(static_cast(0x1)) == "1"));
-
- {
- auto fixed = int_to_string_ary(1234);
- std::string str = lexical_cast(1234);
- REQUIRE(fixed.size() == str.size());
- CHECK(std::equal(fixed.begin(), fixed.end(), str.begin()));
- }
- {
- auto fixed = int_to_string_ary(-1234);
- std::string str = lexical_cast(-1234);
- REQUIRE(fixed.size() == str.size());
- CHECK(std::equal(fixed.begin(), fixed.end(), str.begin()));
- }
-}