Skip to content
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

Add functions for C++ assertions #31

Merged
merged 9 commits into from
Feb 6, 2020
9 changes: 9 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ include_directories(include)
ament_export_include_directories(include)

add_library(${PROJECT_NAME}
src/asserts.cpp
src/find_library.cpp)
target_include_directories(${PROJECT_NAME}
PUBLIC
Expand All @@ -46,6 +47,14 @@ if(BUILD_TESTING)

ament_lint_auto_find_test_dependencies()

ament_add_gtest(test_asserts_ndebug test/test_asserts.cpp)
target_link_libraries(test_asserts_ndebug ${PROJECT_NAME})
zmichaels11 marked this conversation as resolved.
Show resolved Hide resolved

target_compile_definitions(test_asserts_ndebug PUBLIC NDEBUG)

ament_add_gtest(test_asserts_debug test/test_asserts.cpp)
target_link_libraries(test_asserts_debug ${PROJECT_NAME})

ament_add_gtest(test_thread_safety_annotations test/test_thread_safety_annotations.cpp)

ament_add_gtest(test_join test/test_join.cpp)
Expand Down
93 changes: 93 additions & 0 deletions include/rcpputils/asserts.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Licensed 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 RCPPUTILS__ASSERTS_HPP_
#define RCPPUTILS__ASSERTS_HPP_

#include <exception>
#include <stdexcept>
#include <string>

namespace rcpputils
{

class AssertionException : public std::exception
{
std::string msg_;

public:
explicit AssertionException(const std::string & msg)
: msg_{msg} {}

virtual const char * what() const throw();
};

class IllegalStateException : public std::exception
{
std::string msg_;

public:
explicit IllegalStateException(const std::string & msg)
: msg_{msg} {}

virtual const char * what() const throw();
};

/**
* Checks that an argument condition passes.
*
* \param condition
* \throw std::invalid_argument if the condition is not met.
*/
inline void require_true(bool condition)
{
if (!condition) {
throw std::invalid_argument{"Invalid argument passed!"};
}
}

/**
* Checks that a state condition passes.
*
* \param condition
* \throw rcpputils::IllegalStateException if the condition is not met.
*/
inline void check_true(bool condition)
{
if (!condition) {
throw rcpputils::IllegalStateException{"Check reported invalid state!"};
}
}

/**
* Asserts that a condition passes.
*
* This function behaves similar to assert, except that it throws instead of invoking abort().
* \param condition
* \throw rcpputils::AssertionException if the macro NDEBUG is not set and the condition is not met.
*/
inline void assert_true(bool condition)
{
// Same macro definition used by cassert
#ifndef NDEBUG
if (!condition) {
throw rcpputils::AssertionException{"Assertion failed!"};
}
#else
(void) condition;
#endif
}
} // namespace rcpputils

#endif // RCPPUTILS__ASSERTS_HPP_
28 changes: 28 additions & 0 deletions src/asserts.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Licensed 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.

#include "rcpputils/asserts.hpp"

namespace rcpputils
{
const char * AssertionException::what() const throw()
{
return msg_.c_str();
}

const char * IllegalStateException::what() const throw()
{
return msg_.c_str();
}
} // namespace rcpputils
52 changes: 52 additions & 0 deletions test/test_asserts.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Licensed 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.

#include <stdexcept>

#include "gtest/gtest.h"

#include "rcpputils/asserts.hpp"

TEST(test_asserts, require_throws_if_condition_is_false) {
EXPECT_THROW(rcpputils::require_true(false), std::invalid_argument);
}

TEST(test_asserts, require_does_not_throw_if_condition_is_true) {
EXPECT_NO_THROW(rcpputils::require_true(true));
}

TEST(test_asserts, check_throws_if_condition_is_false) {
EXPECT_THROW(rcpputils::check_true(false), rcpputils::IllegalStateException);
}

TEST(test_asserts, check_does_not_throw_if_condition_is_true) {
EXPECT_NO_THROW(rcpputils::check_true(true));
}

#ifndef NDEBUG
TEST(test_asserts, ros_assert_throws_if_condition_is_false_and_ndebug_not_set) {
EXPECT_THROW(rcpputils::assert_true(false), rcpputils::AssertionException);
}

TEST(test_asserts, ros_assert_does_not_throw_if_condition_is_true_and_ndebug_not_set)
{
EXPECT_NO_THROW(rcpputils::assert_true(true));
}

#else
TEST(test_asserts, ros_assert_does_not_throw_if_ndebug_set) {
EXPECT_NO_THROW(rcpputils::assert_true(false));
EXPECT_NO_THROW(rcpputils::assert_true(true));
}
#endif