Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Fix any istype #708

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions include/behaviortree_cpp/scripting/operators.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,17 +101,17 @@ struct ExprUnaryArithmetic : ExprBase
Any evaluate(Environment& env) const override
{
auto rhs_v = rhs->evaluate(env);
if (rhs_v.isNumber())
if (rhs_v.isCastedAsNumber())
{
double rv = rhs_v.cast<double>();
const double rv = rhs_v.cast<double>();
switch (op)
{
case negate:
return Any(-rv);
case complement:
return Any(double(~static_cast<int64_t>(rv)));
return Any(static_cast<double>(~static_cast<int64_t>(rv)));
case logical_not:
return Any(double(!static_cast<bool>(rv)));
return Any(static_cast<double>(!static_cast<bool>(rv)));
}
}
else if (rhs_v.isString())
Expand Down Expand Up @@ -185,7 +185,7 @@ struct ExprBinaryArithmetic : ExprBase
throw RuntimeError(ErrorNotInit("right", opStr()));
}

if (rhs_v.isNumber() && lhs_v.isNumber())
if (rhs_v.isCastedAsNumber() && lhs_v.isCastedAsNumber())
{
auto lv = lhs_v.cast<double>();
auto rv = rhs_v.cast<double>();
Expand Down Expand Up @@ -252,7 +252,7 @@ struct ExprBinaryArithmetic : ExprBase
}
}
}
else if (rhs_v.isType<SimpleString>() && lhs_v.isType<SimpleString>() && op == plus)
else if (rhs_v.isString() && lhs_v.isString() && op == plus)
{
return Any(lhs_v.cast<std::string>() + rhs_v.cast<std::string>());
}
Expand Down Expand Up @@ -362,7 +362,7 @@ struct ExprComparison : ExprBase
}
const Any False(0.0);

if (lhs_v.isNumber() && rhs_v.isNumber())
if (lhs_v.isCastedAsNumber() && rhs_v.isCastedAsNumber())
{
auto lv = lhs_v.cast<double>();
auto rv = rhs_v.cast<double>();
Expand All @@ -380,8 +380,8 @@ struct ExprComparison : ExprBase
return False;
}
}
else if ((lhs_v.isString() && rhs_v.isNumber()) ||
(lhs_v.isNumber() && rhs_v.isString()))
else if ((lhs_v.isString() && rhs_v.isCastedAsNumber()) ||
(lhs_v.isCastedAsNumber() && rhs_v.isString()))
{
auto lv = lhs_v.cast<double>();
auto rv = lhs_v.cast<double>();
Expand Down Expand Up @@ -562,9 +562,9 @@ struct ExprAssignment : ExprBase
// temporary use
Any temp_variable = *dst_ptr;

if (value.isNumber())
if (value.isCastedAsNumber())
{
if (!temp_variable.isNumber())
if (!temp_variable.isCastedAsNumber())
{
throw RuntimeError("This Assignment operator can't be used "
"with a non-numeric type");
Expand Down
82 changes: 55 additions & 27 deletions include/behaviortree_cpp/utils/safe_any.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,23 +69,43 @@ class Any

~Any() = default;

Any(const Any& other) : _any(other._any), _original_type( other._original_type )
Any(const Any& other) :
_any(other._any),
_original_type( other._original_type ),
_is_number( other._is_number ),
_is_integral( other._is_integral )
{
}

Any(Any&& other) : _any( std::move(other._any) ), _original_type( other._original_type )
Any(Any&& other) :
_any( std::move(other._any) ),
_original_type( other._original_type ),
_is_number( other._is_number ),
_is_integral( other._is_integral )
{
}

explicit Any(const double& value) : _any(value), _original_type( typeid(double) )
explicit Any(const double& value) :
_any(value),
_original_type( typeid(double) ),
_is_number(true),
_is_integral(false)
{
}

explicit Any(const uint64_t& value) : _any(value), _original_type( typeid(uint64_t) )
explicit Any(const uint64_t& value) :
_any(value),
_original_type( typeid(uint64_t) ),
_is_number(true),
_is_integral(true)
{
}

explicit Any(const float& value) : _any(double(value)), _original_type( typeid(float) )
explicit Any(const float& value) :
_any(double(value)),
_original_type( typeid(float) ),
_is_number(true),
_is_integral(false)
{
}

Expand All @@ -107,7 +127,11 @@ class Any

// all the other integrals are casted to int64_t
template <typename T>
explicit Any(const T& value, EnableIntegral<T> = 0) : _any(int64_t(value)), _original_type( typeid(T) )
explicit Any(const T& value, EnableIntegral<T> = 0) :
_any(int64_t(value)),
_original_type( typeid(T) ),
_is_number(true),
_is_integral(true)
{
}

Expand All @@ -124,9 +148,15 @@ class Any

Any& operator = (const Any& other);

[[nodiscard]] bool isNumber() const;
[[nodiscard]] ool isNumber() const
{
return _is_number;
}

[[nodiscard]] bool isIntegral() const;
[[nodiscard]] ool isIntegral() const
{
return _is_integral;
}

[[nodiscard]] bool isString() const
{
Expand All @@ -136,7 +166,14 @@ class Any
template <typename T>
[[nodiscard]] bool isType() const
{
return _any.type() == typeid(T);
return type() == typeid(T);
}

bool isCastedAsNumber() const
{
return _any.type() == typeid(int64_t) ||
_any.type() == typeid(uint64_t) ||
_any.type() == typeid(double);
}

// copy the value (casting into dst). We preserve the destination type.
Expand Down Expand Up @@ -188,6 +225,8 @@ class Any
private:
linb::any _any;
std::type_index _original_type;
bool _is_number = false;
bool _is_integral = false;

//----------------------------

Expand All @@ -210,7 +249,7 @@ class Any
std::string errorMsg() const
{
return StrCat("[Any::convert]: no known safe conversion between [",
demangle( _any.type() ), "] and [", demangle( typeid(T) ),"]");
demangle( type() ), "] and [", demangle( typeid(T) ),"]");
}
};

Expand Down Expand Up @@ -270,22 +309,11 @@ inline Any &Any::operator =(const Any &other)
{
this->_any = other._any;
this->_original_type = other._original_type;
this->_is_number = other._is_number;
this->_is_integral = other._is_integral;
return *this;
}

inline bool Any::isNumber() const
{
return _any.type() == typeid(int64_t) ||
_any.type() == typeid(uint64_t) ||
_any.type() == typeid(double);
}

inline bool Any::isIntegral() const
{
return _any.type() == typeid(int64_t) ||
_any.type() == typeid(uint64_t);
}

inline void Any::copyInto(Any &dst)
{
if(dst.empty())
Expand All @@ -296,11 +324,11 @@ inline void Any::copyInto(Any &dst)

const auto& dst_type = dst.castedType();

if ((type() == dst_type) || (isString() && dst.isString()) )
if ((castedType() == dst_type) || (isString() && dst.isString()) )
{
dst._any = _any;
}
else if(isNumber() && dst.isNumber())
else if(isCastedAsNumber() && dst.isCastedAsNumber())
{
if (dst_type == typeid(int64_t))
{
Expand Down Expand Up @@ -446,7 +474,7 @@ nonstd::expected<T, std::string> Any::tryCast() const
throw std::runtime_error("Any::cast failed because it is empty");
}

if (_any.type() == typeid(T))
if (castedType() == typeid(T))
{
return linb::any_cast<T>(_any);
}
Expand All @@ -455,7 +483,7 @@ nonstd::expected<T, std::string> Any::tryCast() const
// We will try first a int convertion
if constexpr(std::is_enum_v<T>)
{
if(isNumber())
if(isCastedAsNumber())
{
return static_cast<T>( convert<int>().value() );
}
Expand Down
2 changes: 1 addition & 1 deletion src/blackboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ Blackboard::createEntryImpl(const std::string& key, const TypeInfo& info)
auto msg = StrCat("Blackboard entry [", key, "]: once declared, the type of a port"
" shall not change. Previously declared type [",
BT::demangle(prev_info.type()),
"], current type [",
"], attempt type [",
BT::demangle(info.type()), "]");

throw LogicError(msg);
Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ set(BT_TESTS
src/action_test_node.cpp
src/condition_test_node.cpp

gtest_any.cpp
gtest_blackboard.cpp
gtest_coroutines.cpp
gtest_decorator.cpp
Expand Down
Loading