Skip to content

Commit

Permalink
Add more documentation and include doxyfile
Browse files Browse the repository at this point in the history
Signed-off-by: Stephen Brawner <brawner@gmail.com>
  • Loading branch information
brawner committed Feb 29, 2020
1 parent f02715b commit 4573a42
Show file tree
Hide file tree
Showing 13 changed files with 552 additions and 98 deletions.
29 changes: 29 additions & 0 deletions Doxyfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# All settings not listed here will use the Doxygen default values.

PROJECT_NAME = "rcpputils"
PROJECT_NUMBER = master
PROJECT_BRIEF = "C++ API providing common utilities and data structures."

# Use these lines to include the generated logging_macro.h (update install path if needed)
INPUT = README.md ./include ./docs
USE_MDFILE_AS_MAINPAGE = README.md
RECURSIVE = YES
OUTPUT_DIRECTORY = doc_output

EXTRACT_ALL = YES
SORT_MEMBER_DOCS = NO

GENERATE_LATEX = NO
EXCLUDE_SYMBOLS = detail details

ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
PREDEFINED += __declspec(x)=
PREDEFINED += RCPPUTILS_PUBLIC=
PREDEFINED += RCPPUTILS_PUBLIC_TYPE=

# Tag files that do not exist will produce a warning and cross-project linking will not work.
TAGFILES += "../../../doxygen_tag_files/cppreference-doxygen-web.tag.xml=http://en.cppreference.com/w/"
# Uncomment to generate tag files for cross-project linking.
#GENERATE_TAGFILE = "../../../doxygen_tag_files/rcpputils.tag"
48 changes: 2 additions & 46 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

`rcpputils` is a C++ API consisting of macros, functions, and data structures intended for use throughout the ROS 2 codebase

## API
This package currently contains:
* Assertion functions
* Clang thread safety annotation macros
Expand All @@ -10,49 +11,4 @@ This package currently contains:
* File system helpers
* Type traits helpers

## Assertion Functions
The [rcpputils/asserts.hpp](rcpputils/include/rcpputils/asserts.hpp) header provides the helper functions:
* `require_true`: for validating function inputs. Throws an `std::invalid_argument` exception if the condition fails.
* `check_true`: for checking states. Throws an `rcpputils::InvalidStateException` if the condition fails.
* `assert_true`: for verifying results. Throws an `rcpputils::AssertionException` if the condition fails. This function becomes a no-op in release builds.

These helper functions can be used to improve readability of C++ functions.
Example usage:
```c++
ResultType some_function(ArgType arg)
{
// Check if the required internal state for calling `some_function` is valid.
// There's usually no reason to operate on the input if the state is invalid.
rcpputils::check_true(internal_state.is_valid);

// Check if the arguments are valid.
// It's usually best practice to only process valid inputs.
rcpputils::require_true(arg.is_valid);

auto result = do_logic(arg);

// Assert that the result is valid.
// This will only throw when ran in debug mode if result is invalid.
// Throwing early when invalid may help find points of error when debugging.
rcpputils::assert_true(result.is_valid);
return result
}
```
## Clang Thread Safety Annotation Macros
the `rcpputils/thread_safety_annotations.hpp` header provides macros for Clang's [Thread Safety Analysis](https://clang.llvm.org/docs/ThreadSafetyAnalysis.html) feature.
The macros allow you to annotate your code, but expand to nothing when using a non-clang compiler, so they are safe for cross-platform use.
To use thread safety annotation in your package (in a Clang+libcxx build), enable the `-Wthread-safety` compiler flag.
For example usage, see [the documentation of this feature](https://clang.llvm.org/docs/ThreadSafetyAnalysis.html) and the tests in `test/test_basic.cpp`
## Library Discovery
In `rcpputils/find_library.hpp`:
* `find_library(library_name)`: Namely used for dynamically loading RMW
implementations.
* For dynamically loading user-defind plugins in C++, please use
[`pluginlib`](https://github.com/ros/pluginlib) instead.
Features are described in more detail at [docs/FEATURES.md](docs/FEATURES.md)
77 changes: 77 additions & 0 deletions docs/FEATURES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# rcpputils Features

This package includes the following convenience functions for generally cross-platform c++ functionality:
* [Assertion functions](#assertion-functions)
* [Clang thread safety annotation macros](#clang-thread-safety-annotation-macros)
* [Endianness helpers](#endianness-helpers)
* [Library discovery](#library-discovery)
* [String helpers](#string-helpers)
* [File system helpers](#file-system-helpers)
* [Type traits helpers](#type-traits-helpers)
* [Visibility macros](#visibility-macros)

## Assertion Functions {#assertion-functions}
The [rcpputils/asserts.hpp](rcpputils/include/rcpputils/asserts.hpp) header provides the helper functions:
* `require_true`: for validating function inputs. Throws an `std::invalid_argument` exception if the condition fails.
* `check_true`: for checking states. Throws an `rcpputils::InvalidStateException` if the condition fails.
* `assert_true`: for verifying results. Throws an `rcpputils::AssertionException` if the condition fails. This function becomes a no-op in release builds.

These helper functions can be used to improve readability of C++ functions.
Example usage:
```c++
ResultType some_function(ArgType arg)
{
// Check if the required internal state for calling `some_function` is valid.
// There's usually no reason to operate on the input if the state is invalid.
rcpputils::check_true(internal_state.is_valid);

// Check if the arguments are valid.
// It's usually best practice to only process valid inputs.
rcpputils::require_true(arg.is_valid);

auto result = do_logic(arg);

// Assert that the result is valid.
// This will only throw when ran in debug mode if result is invalid.
// Throwing early when invalid may help find points of error when debugging.
rcpputils::assert_true(result.is_valid);
return result
}
```
## Clang Thread Safety Annotation Macros {#clang-thread-safety-annotation-macros}
the `rcpputils/thread_safety_annotations.hpp` header provides macros for Clang's [Thread Safety Analysis](https://clang.llvm.org/docs/ThreadSafetyAnalysis.html) feature.
The macros allow you to annotate your code, but expand to nothing when using a non-clang compiler, so they are safe for cross-platform use.
To use thread safety annotation in your package (in a Clang+libcxx build), enable the `-Wthread-safety` compiler flag.
For example usage, see [the documentation of this feature](https://clang.llvm.org/docs/ThreadSafetyAnalysis.html) and the tests in `test/test_basic.cpp`
## Endianness helpers {#endianness-helpers}
In `rcpputils/endian.hpp`
Emulates the features of std::endian if it is not available. See [cppreference](https://en.cppreference.com/w/cpp/types/endian) for more information.
## Library Discovery {#library-discovery}
In `rcpputils/find_library.hpp`:
* `find_library(library_name)`: Namely used for dynamically loading RMW
implementations.
* For dynamically loading user-defined plugins in C++, please use
[`pluginlib`](https://github.com/ros/pluginlib) instead.
## String Helpers {#string-helpers}
In `rcpputils/join.hpp` and `rcpputils/split.hpp`
These headers include simple functions for joining a container into a single string and splitting a string into a container of values.
## File system helpers {#file-system-helpers}
`rcpputils/filesystem_helper.hpp` provides `std::filesystem`-like functionality on systems that do not yet include those features. See the [cppreference](https://en.cppreference.com/w/cpp/header/filesystem) for more information.
## Type traits helpers {#type-traits-helpers}
`rcpputils/pointer_traits.hpp` provides several type trait definitions for pointers and smart pointers.
## Visibility definitions and macros {#visibility-definitions-and-macros}
`rcpputils/visibility_control.hpp` provides macros and definitions for controlling the visibility of class members. The logic was borrowed and then namespaced from [https://gcc.gnu.org/wiki/Visibility](https://gcc.gnu.org/wiki/Visibility).
52 changes: 43 additions & 9 deletions include/rcpputils/asserts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.

/*! \file asserts.hpp
* \brief Assertion-like exceptions for halting tests.
*/

#ifndef RCPPUTILS__ASSERTS_HPP_
#define RCPPUTILS__ASSERTS_HPP_

Expand All @@ -33,31 +37,59 @@
namespace rcpputils
{

/**
* \brief An assertion-like exception for halting tests if conditions are not met.
*/
class RCPPUTILS_PUBLIC AssertionException : public std::exception
{
std::string msg_;

public:
/**
* \brief Constructor for AssertionException
*
* \param msg The message to display when this exception is thrown.
*/
explicit AssertionException(const char * msg);

/**
* \brief Get the message description of why this exception was thrown.
*
* \return The string message
*/
virtual const char * what() const throw();
};

/**
* \brief An exception to be thrown when a state check fails.
*/

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

public:
/**
* \brief Constructor for IllegalStateException
*
* \param msg The message to display when this exception is thrown.
*/

explicit IllegalStateException(const char * msg);

/**
* \brief Get the message description of why this exception was thrown.
*
* \return The string message
*/
virtual const char * what() const throw();
};

/**
* Checks that an argument condition passes.
* \brief Checks that an argument condition passes.
*
* \param condition
* \param msg
* \param condition condition that is asserted to be true
* \param msg message to pass to exception when condition is false
* \throw std::invalid_argument if the condition is not met.
*/
inline void require_true(bool condition, const std::string & msg = "invalid argument passed")
Expand All @@ -68,10 +100,10 @@ inline void require_true(bool condition, const std::string & msg = "invalid argu
}

/**
* Checks that a state condition passes.
* \brief Checks that a state condition passes.
*
* \param condition
* \param msg
* \param condition condition to check whether it is true or not
* \param msg message to pass to exception when condition is false
* \throw rcpputils::IllegalStateException if the condition is not met.
*/
inline void check_true(bool condition, const std::string & msg = "check reported invalid state")
Expand All @@ -82,11 +114,13 @@ inline void check_true(bool condition, const std::string & msg = "check reported
}

/**
* Asserts that a condition passes.
* \brief Asserts that a condition passes.
*
* This function behaves similar to assert, except that it throws instead of invoking abort().
* \param condition
* \param msg
* It is only enabled when NDEBUG is not defined
*
* \param condition condition to check whether it's true or not
* \param msg message to pass to exception when condition is not met.
* \throw rcpputils::AssertionException if the macro NDEBUG is not set and the condition is not met.
*/
inline void assert_true(bool condition, const std::string & msg = "assertion failed")
Expand Down
15 changes: 10 additions & 5 deletions include/rcpputils/endian.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

/**
* If std::endian is not available, the necessary functions are emulated.
/*! \file endian.hpp
* \brief If std::endian is not available, the necessary functions are emulated.
*
* Note: Once std::endian is supported on all ROS2 platforms, this class
* can be deprecated in favor of the built-in functionality.
Expand Down Expand Up @@ -47,9 +47,14 @@ using std::endian;

namespace rcpputils
{
// Ref: https://en.cppreference.com/w/cpp/types/endian#Possible_implementation
// From: https://en.cppreference.com/w/Cppreference:FAQ, this is licensed
// Creative Commons Attribution-Sharealike 3.0 Unported License (CC-BY-SA)
/*! \enum endian
* \brief Type traits for defining the endianness at compile-time.
*
* [cppreference.com documentation](https://en.cppreference.com/w/cpp/types/endian#Possible_implementation)
*
* From: https://en.cppreference.com/w/Cppreference:FAQ, this is licensed Creative Commons
* Attribution-Sharealike 3.0 Unported License (CC-BY-SA)
*/
enum class endian
{
#ifdef _WIN32
Expand Down
Loading

0 comments on commit 4573a42

Please sign in to comment.