diff options
author | Christopher Friedt <cfriedt@meta.com> | 2022-10-01 17:21:26 -0400 |
---|---|---|
committer | Jens Geyer <Jens-G@users.noreply.github.com> | 2022-11-20 12:05:39 +0100 |
commit | 6e9cbbd059b00741c886b252cc63d325e4d86e22 (patch) | |
tree | 6309599a35205f9105c2236639142fcfabfd057e /lib/cpp | |
parent | f525e4cbb6a6bf81fbbd4edf7e3f6318823a8e9f (diff) | |
download | thrift-6e9cbbd059b00741c886b252cc63d325e4d86e22.tar.gz |
lib: cpp: TTransportException: create thrift::numeric_cast
This adds an equivalent implementation of `boost::numeric_cast`
written purely in standard c++.
The implementation is relatively trivial and reduces the
dependency on `boost`.
Adapted from
https://stackoverflow.com/a/49658950/5636218
Signed-off-by: Chris Friedt <cfriedt@meta.com>
Diffstat (limited to 'lib/cpp')
-rw-r--r-- | lib/cpp/src/thrift/numeric_cast.h | 70 | ||||
-rw-r--r-- | lib/cpp/src/thrift/transport/TTransportException.h | 5 |
2 files changed, 73 insertions, 2 deletions
diff --git a/lib/cpp/src/thrift/numeric_cast.h b/lib/cpp/src/thrift/numeric_cast.h new file mode 100644 index 000000000..d7063dbc6 --- /dev/null +++ b/lib/cpp/src/thrift/numeric_cast.h @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef THRIFT_NUMERIC_CAST_H +#define THRIFT_NUMERIC_CAST_H + +#include <limits> +#include <stdexcept> + +#if defined(_MSC_VER) +// avoid compiler warnings and errors in MSVC if max is defined as a macro +#undef max +#endif + +namespace apache { +namespace thrift { + +/** + * @brief Perform a safe numeric cast + * + * Previously this was provided by `boost::numeric_cast`. This + * implementation reduces the dependency on `boost`. + * + * @tparam Dst The destination type + * @tparam Src The source type + * @param value The value to be converted + * @return Dst The converted value + * + * @see <a href="https://stackoverflow.com/a/49658950/5636218">SA49658182</a> + */ +template <typename Dst, typename Src> +inline Dst numeric_cast(Src value) { + typedef std::numeric_limits<Dst> DstLim; + typedef std::numeric_limits<Src> SrcLim; + + const bool positive_overflow_possible = DstLim::max() < SrcLim::max(); + const bool negative_overflow_possible = DstLim::lowest() > SrcLim::lowest(); + + if (positive_overflow_possible && value > DstLim::max()) { + throw std::bad_cast(); + } + + if (negative_overflow_possible && (value < DstLim::lowest())) { + throw std::bad_cast(); + } + + // limits have been checked, therefore safe to cast + return static_cast<Dst>(value); +} + +} // namespace thrift +} // namespace apache + +#endif diff --git a/lib/cpp/src/thrift/transport/TTransportException.h b/lib/cpp/src/thrift/transport/TTransportException.h index dd5f361f1..3ce55cb76 100644 --- a/lib/cpp/src/thrift/transport/TTransportException.h +++ b/lib/cpp/src/thrift/transport/TTransportException.h @@ -20,8 +20,9 @@ #ifndef _THRIFT_TRANSPORT_TTRANSPORTEXCEPTION_H_ #define _THRIFT_TRANSPORT_TTRANSPORTEXCEPTION_H_ 1 -#include <boost/numeric/conversion/cast.hpp> #include <string> + +#include <thrift/numeric_cast.h> #include <thrift/Thrift.h> namespace apache { @@ -92,7 +93,7 @@ protected: */ template <typename To, typename From> To safe_numeric_cast(From i) { try { - return boost::numeric_cast<To>(i); + return apache::thrift::numeric_cast<To>(i); } catch (const std::bad_cast& bc) { throw TTransportException(TTransportException::CORRUPTED_DATA, |