From 39cfbada85a1d8493350413f2dc935258f36da01 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Sat, 13 Oct 2018 12:34:56 +0100 Subject: [PATCH] Use the new int_conv instead of the old lexical_cast. --- include/incredis/int_conv.hpp | 95 +++++++++++++++++++++++++++++++++++ include/incredis/script.hpp | 4 +- lib/duckhandy | 2 +- src/incredis.cpp | 9 ++-- src/incredis_batch.cpp | 8 +-- src/reply.cpp | 6 +-- src/scan_iterator.cpp | 10 ++-- src/script_manager.cpp | 16 +++--- 8 files changed, 120 insertions(+), 30 deletions(-) create mode 100644 include/incredis/int_conv.hpp diff --git a/include/incredis/int_conv.hpp b/include/incredis/int_conv.hpp new file mode 100644 index 0000000..3d70f8d --- /dev/null +++ b/include/incredis/int_conv.hpp @@ -0,0 +1,95 @@ +/* Copyright 2016-2018, Michele Santullo + * This file is part of "incredis". + * + * "incredis" 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. + * + * "incredis" 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 "incredis". If not, see . + */ + +#ifndef id08E89EF0951741388A48A79E769C646C +#define id08E89EF0951741388A48A79E769C646C + +#include +#include +#include "duckhandy/implem/int_conv.hpp" + +namespace redis { + namespace implem { + struct AsciiTranslator { + static const constexpr bool BehavesLikeASCII = true; + static const constexpr char FirstDigit = '0'; + static const constexpr char FirstLetter = 'a'; + static const constexpr char Plus = '+'; + static const constexpr char Minus = '-'; + + static constexpr char to_digit (unsigned int num) { + return (num <= 9 ? static_cast(num + '0') : static_cast(num + 'a')); + } + + static constexpr int from_digit (char digit) { + if (digit >= '0' and digit <= '9') + return digit - '0'; + else if (digit >= 'a' and digit <= 'z') + return digit - 'a'; + else if (digit >= 'A' and digit <= 'Z') + return digit - 'A'; + else + throw std::domain_error( + std::string("Can't convert invalid character '") + + digit + "' (" + + std::to_string(static_cast(digit)) + + ") to a number" + ); + } + }; + + template + struct IntConv; + + template + struct IntConv, std::string>, F> { + static std::string conv (const F& in) { + auto retval = dhandy::int_to_ary(in); + return std::string(retval.begin(), retval.end() - 1); + } + }; + template + struct IntConv, std::string>> { + static T conv (const std::string& in) { + return dhandy::ary_to_int(in.data(), in.data() + in.size()); + } + }; + template + struct IntConv, std::string_view>> { + static T conv (const std::string_view& in) { + return dhandy::ary_to_int(in.data(), in.data() + in.size()); + } + }; + } //namespace implem + + template + inline To int_conv (const From& from) { + return implem::IntConv::conv(from); + } + + template + constexpr inline auto int_to_ary_hex (From f) { + return dhandy::int_to_ary(f); + } + + template + constexpr inline auto int_to_ary_dec (From f) { + return dhandy::int_to_ary(f); + } +} //namespace redis + +#endif diff --git a/include/incredis/script.hpp b/include/incredis/script.hpp index 0758d21..b91ee3e 100644 --- a/include/incredis/script.hpp +++ b/include/incredis/script.hpp @@ -19,7 +19,7 @@ #define id5B30CDA57F894CD6888093B64F9433DA #include "batch.hpp" -#include "duckhandy/lexical_cast.hpp" +#include "incredis/int_conv.hpp" #include "duckhandy/sequence_bt.hpp" #include #include @@ -73,7 +73,7 @@ namespace redis { parBatch.run( "EVALSHA", m_sha1, - dhandy::lexical_cast(sizeof...(Keys)), + int_conv(sizeof...(Keys)), std::get(parKeys)..., std::get(parValues)... ); diff --git a/lib/duckhandy b/lib/duckhandy index 7ceaf01..4eb4209 160000 --- a/lib/duckhandy +++ b/lib/duckhandy @@ -1 +1 @@ -Subproject commit 7ceaf01a376e9184027850104dac4f3e3fc6b755 +Subproject commit 4eb42094093a3eb899d6e8169959dfa8985f3cb6 diff --git a/src/incredis.cpp b/src/incredis.cpp index f2f319b..5c1eb74 100644 --- a/src/incredis.cpp +++ b/src/incredis.cpp @@ -17,7 +17,7 @@ #include "incredis.hpp" #include "duckhandy/compatibility.h" -#include "duckhandy/lexical_cast.hpp" +#include "incredis/int_conv.hpp" #include #include @@ -102,13 +102,12 @@ namespace redis { } RedisInt IncRedis::hincrby (boost::string_view parKey, boost::string_view parField, int parInc) { - const auto inc = dhandy::lexical_cast(parInc); - auto reply = m_command.run("HINCRBY", parKey, parField, inc); + auto reply = m_command.run("HINCRBY", parKey, parField, int_to_ary_dec(parInc).to()); return get_integer(reply); } auto IncRedis::srandmember (boost::string_view parKey, int parCount) -> opt_string_list { - return optional_string_list(m_command.run("SRANDMEMBER", parKey, dhandy::lexical_cast(parCount))); + return optional_string_list(m_command.run("SRANDMEMBER", parKey, int_to_ary_dec(parCount).to())); } auto IncRedis::srandmember (boost::string_view parKey) -> opt_string { @@ -142,7 +141,7 @@ namespace redis { } bool IncRedis::expire (boost::string_view parKey, RedisInt parTTL) { - const auto ret = redis::get(m_command.run("EXPIRE", parKey, dhandy::lexical_cast(parTTL))); + const auto ret = redis::get(m_command.run("EXPIRE", parKey, int_to_ary_dec(parTTL).to())); return (ret == 1 ? true : false); } diff --git a/src/incredis_batch.cpp b/src/incredis_batch.cpp index 0c5626a..7bcddde 100644 --- a/src/incredis_batch.cpp +++ b/src/incredis_batch.cpp @@ -16,7 +16,7 @@ */ #include "incredis_batch.hpp" -#include "duckhandy/lexical_cast.hpp" +#include "incredis/int_conv.hpp" #include #include #include @@ -45,7 +45,7 @@ namespace redis { } IncRedisBatch& IncRedisBatch::select (int parIndex) { - m_batch.run("SELECT", dhandy::lexical_cast(parIndex)); + m_batch.run("SELECT", int_to_ary_dec(parIndex).to()); return *this; } @@ -60,12 +60,12 @@ namespace redis { } IncRedisBatch& IncRedisBatch::hincrby (boost::string_view parKey, boost::string_view parField, int parInc) { - m_batch.run("HINCRBY", parKey, parField, dhandy::lexical_cast(parInc)); + m_batch.run("HINCRBY", parKey, parField, int_to_ary_dec(parInc).to()); return *this; } IncRedisBatch& IncRedisBatch::srandmember (boost::string_view parKey, int parCount) { - m_batch.run("SRANDMEMBER", parKey, dhandy::lexical_cast(parCount)); + m_batch.run("SRANDMEMBER", parKey, int_to_ary_dec(parCount).to()); return *this; } diff --git a/src/reply.cpp b/src/reply.cpp index 5b40126..8ae1e86 100644 --- a/src/reply.cpp +++ b/src/reply.cpp @@ -16,7 +16,7 @@ */ #include "reply.hpp" -#include "duckhandy/lexical_cast.hpp" +#include "incredis/int_conv.hpp" #include namespace redis { @@ -35,14 +35,12 @@ namespace redis { } RedisInt get_integer_autoconv_if_str (const Reply &parReply) { - using dhandy::lexical_cast; - const auto type = parReply.which(); switch (type) { case RedisVariantType_Integer: return get_integer(parReply); case RedisVariantType_String: - return lexical_cast(get_string(parReply)); + return int_conv(get_string(parReply)); default: assert(false); return 0; diff --git a/src/scan_iterator.cpp b/src/scan_iterator.cpp index 8695951..0f2a5ea 100644 --- a/src/scan_iterator.cpp +++ b/src/scan_iterator.cpp @@ -16,7 +16,7 @@ */ #include "scan_iterator.hpp" -#include "duckhandy/lexical_cast.hpp" +#include "incredis/int_conv.hpp" #include "command.hpp" #include #include @@ -42,8 +42,8 @@ namespace redis { } Reply ScanIteratorBaseClass::run (const char* parCommand, RedisInt parScanContext, std::size_t parCount) { - const auto scan_context = dhandy::lexical_cast(parScanContext); - const auto count_hint = dhandy::lexical_cast(parCount); + const auto scan_context = int_conv(parScanContext); + const auto count_hint = int_conv(parCount); if (m_match_pattern.empty()) return m_command->run(parCommand, scan_context, "COUNT", count_hint); else @@ -51,8 +51,8 @@ namespace redis { } Reply ScanIteratorBaseClass::run (const char* parCommand, const boost::string_view& parParameter, RedisInt parScanContext, std::size_t parCount) { - const auto scan_context = dhandy::lexical_cast(parScanContext); - const auto count_hint = dhandy::lexical_cast(parCount); + const auto scan_context = int_conv(parScanContext); + const auto count_hint = int_conv(parCount); if (m_match_pattern.empty()) return m_command->run(parCommand, parParameter, scan_context, "COUNT", count_hint); else diff --git a/src/script_manager.cpp b/src/script_manager.cpp index 56037f7..0094d10 100644 --- a/src/script_manager.cpp +++ b/src/script_manager.cpp @@ -16,7 +16,7 @@ */ #include "script_manager.hpp" -#include "duckhandy/lexical_cast.hpp" +#include "incredis/int_conv.hpp" #include "command.hpp" #include #if defined(MAKE_SHA1_WITH_CRYPTOPP) @@ -51,8 +51,6 @@ namespace redis { if (parScript.empty()) return boost::string_view(); - using dhandy::lexical_cast; - static_assert(20 == CryptoPP::SHA1::DIGESTSIZE, "Unexpected SHA1 digest size"); static_assert(sizeof(LuaScriptHash) >= CryptoPP::SHA1::DIGESTSIZE, "Wrong SHA1 struct size"); static_assert(Sha1Array().size() == CryptoPP::SHA1::DIGESTSIZE * 2, "Wrong array size"); @@ -60,13 +58,13 @@ namespace redis { LuaScriptHash digest; CryptoPP::SHA1().CalculateDigest(digest.raw_bytes, reinterpret_cast(parScript.data()), parScript.size()); //TODO: change when lexical_cast will support arrays - auto sha1_str_parta = lexical_cast(__builtin_bswap64(digest.part_a)); - auto sha1_str_partb = lexical_cast(__builtin_bswap64(digest.part_b)); - auto sha1_str_partc = lexical_cast(__builtin_bswap32(digest.part_c)); + auto sha1_str_parta = int_to_ary_hex(__builtin_bswap64(digest.part_a)); + auto sha1_str_partb = int_to_ary_hex(__builtin_bswap64(digest.part_b)); + auto sha1_str_partc = int_to_ary_hex(__builtin_bswap32(digest.part_c)); const std::string sha1_str = - std::string(sizeof(digest.part_a) * 2 - sha1_str_parta.size(), '0') + sha1_str_parta + - std::string(sizeof(digest.part_b) * 2 - sha1_str_partb.size(), '0') + sha1_str_partb + - std::string(sizeof(digest.part_c) * 2 - sha1_str_partc.size(), '0') + sha1_str_partc + std::string(sizeof(digest.part_a) * 2 - sha1_str_parta.size() + 1, '0') + sha1_str_parta + + std::string(sizeof(digest.part_b) * 2 - sha1_str_partb.size() + 1, '0') + sha1_str_partb + + std::string(sizeof(digest.part_c) * 2 - sha1_str_partc.size() + 1, '0') + sha1_str_partc ; Sha1Array sha1_array; assert(sha1_str.size() == sha1_array.size());