diff --git a/rcl/include/rcl/remap.h b/rcl/include/rcl/remap.h
index a7b10ea93..82f0b0e04 100644
--- a/rcl/include/rcl/remap.h
+++ b/rcl/include/rcl/remap.h
@@ -247,6 +247,31 @@ rcl_remap_node_namespace(
rcl_allocator_t allocator,
char ** output_namespace);
+/// Copy one remap structure into another.
+/**
+ *
+ * Attribute | Adherence
+ * ------------------ | -------------
+ * Allocates Memory | Yes
+ * Thread-Safe | No
+ * Uses Atomics | No
+ * Lock-Free | Yes
+ *
+ * \param[in] rule The structure to be copied.
+ * Its allocator is used to copy memory into the new structure.
+ * \param[out] rule_out A zero-initialized rcl_remap_t structure to be copied into.
+ * \return `RCL_RET_OK` if the structure was copied successfully, or
+ * \return `RCL_RET_INVALID_ARGUMENT` if any function arguments are invalid, or
+ * \return `RCL_RET_BAD_ALLOC` if allocating memory failed, or
+ * \return `RCL_RET_ERROR` if an unspecified error occurs.
+ */
+RCL_PUBLIC
+RCL_WARN_UNUSED
+rcl_ret_t
+rcl_remap_copy(
+ const rcl_remap_t * rule,
+ rcl_remap_t * rule_out);
+
/// Reclaim resources held inside rcl_remap_t structure.
/**
*
diff --git a/rcl/src/rcl/remap_impl.h b/rcl/src/rcl/remap_impl.h
index de8e835f8..898e58cb7 100644
--- a/rcl/src/rcl/remap_impl.h
+++ b/rcl/src/rcl/remap_impl.h
@@ -51,57 +51,6 @@ typedef struct rcl_remap_impl_t
rcl_allocator_t allocator;
} rcl_remap_impl_t;
-/// Get an rcl_remap_t structure initialized with NULL.
-rcl_remap_t
-rcl_remap_get_zero_initialized();
-
-/// Copy one remap structure into another.
-/**
- *
- * Attribute | Adherence
- * ------------------ | -------------
- * Allocates Memory | Yes
- * Thread-Safe | No
- * Uses Atomics | No
- * Lock-Free | Yes
- *
- * \param[in] rule The structure to be copied.
- * Its allocator is used to copy memory into the new structure.
- * \param[out] rule_out A zero-initialized rcl_remap_t structure to be copied into.
- * \return `RCL_RET_OK` if the structure was copied successfully, or
- * \return `RCL_RET_INVALID_ARGUMENT` if any function arguments are invalid, or
- * \return `RCL_RET_BAD_ALLOC` if allocating memory failed, or
- * \return `RCL_RET_ERROR` if an unspecified error occurs.
- */
-RCL_PUBLIC
-RCL_WARN_UNUSED
-rcl_ret_t
-rcl_remap_copy(
- const rcl_remap_t * rule,
- rcl_remap_t * rule_out);
-
-/// Reclaim resources used in an rcl_remap_t structure.
-/**
- *
- * Attribute | Adherence
- * ------------------ | -------------
- * Allocates Memory | No
- * Thread-Safe | Yes
- * Uses Atomics | No
- * Lock-Free | Yes
- *
- * \param[in] rule A rule to deallocate back to a zero initialized state.
- * \return `RCL_RET_OK` if the structure was free'd, or
- * \return `RCL_RET_INVALID_ARGUMENT` if any arguments are invalid, or
- * \return `RCL_RET_BAD_ALLOC` if allocating memory failed, or
- * \return `RCL_RET_NODE_INVALID_NAME` if the name is invalid, or
- * \return `RCL_RET_ERROR` if an unspecified error occurs.
- */
-RCL_WARN_UNUSED
-rcl_ret_t
-rcl_remap_fini(
- rcl_remap_t * rule);
-
#ifdef __cplusplus
}
#endif
diff --git a/rcl/test/rcl/test_remap.cpp b/rcl/test/rcl/test_remap.cpp
index 1b0d2eb0e..f2dca9dbe 100644
--- a/rcl/test/rcl/test_remap.cpp
+++ b/rcl/test/rcl/test_remap.cpp
@@ -19,10 +19,9 @@
#include "rcl/remap.h"
#include "rcl/error_handling.h"
+#include "./allocator_testing_utils.h"
#include "./arg_macros.hpp"
#include "./arguments_impl.h"
-#include "./allocator_testing_utils.h"
-#include "./remap_impl.h"
#ifdef RMW_IMPLEMENTATION
# define CLASSNAME_(NAME, SUFFIX) NAME ## __ ## SUFFIX
@@ -574,3 +573,43 @@ TEST_F(CLASSNAME(TestRemapFixture, RMW_IMPLEMENTATION), _rcl_remap_name_bad_arg)
EXPECT_EQ(RCL_RET_ERROR, ret);
rcl_reset_error();
}
+
+TEST_F(CLASSNAME(TestRemapFixture, RMW_IMPLEMENTATION), internal_remap_use) {
+ // Easiest way to init a rcl_remap is through the arguments API
+ const char * argv[] = {
+ "process_name", "--ros-args", "-r", "__ns:=/namespace", "random:=arg"
+ };
+ int argc = sizeof(argv) / sizeof(const char *);
+ rcl_allocator_t alloc = rcl_get_default_allocator();
+ rcl_arguments_t parsed_args = rcl_get_zero_initialized_arguments();
+
+ rcl_ret_t ret = rcl_parse_arguments(argc, argv, alloc, &parsed_args);
+ ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
+ OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT(
+ {
+ EXPECT_EQ(RCL_RET_OK, rcl_arguments_fini(&parsed_args));
+ });
+
+ // Bad alloc
+ rcl_remap_t remap_dst = rcl_get_zero_initialized_remap();
+ parsed_args.impl->remap_rules->impl->allocator = get_failing_allocator();
+ EXPECT_EQ(RCL_RET_BAD_ALLOC, rcl_remap_copy(parsed_args.impl->remap_rules, &remap_dst));
+ parsed_args.impl->remap_rules->impl->allocator = alloc;
+
+ // Expected usage
+ EXPECT_EQ(RCL_RET_OK, rcl_remap_copy(parsed_args.impl->remap_rules, &remap_dst));
+
+ // Copy twice
+ EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, rcl_remap_copy(parsed_args.impl->remap_rules, &remap_dst));
+ rcl_reset_error();
+
+ // Fini
+ EXPECT_EQ(RCL_RET_OK, rcl_remap_fini(&remap_dst));
+
+ // Fini twice
+ EXPECT_EQ(RCL_RET_ERROR, rcl_remap_fini(&remap_dst));
+ rcl_reset_error();
+
+ // Bad fini
+ EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, rcl_remap_fini(nullptr));
+}