diff --git a/CMakeLists.txt b/CMakeLists.txt index 92b3505..48d9c35 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,6 +33,8 @@ if(BUILD_TESTING) ament_add_gtest(test_basic test/test_basic.cpp) + ament_add_gtest(test_join test/test_join.cpp) + ament_add_gtest(test_split test/test_split.cpp) ament_add_gtest(test_filesystem_helper test/test_filesystem_helper.cpp) diff --git a/include/rcpputils/join.hpp b/include/rcpputils/join.hpp new file mode 100644 index 0000000..a1f64c2 --- /dev/null +++ b/include/rcpputils/join.hpp @@ -0,0 +1,71 @@ +// Copyright (c) 2019, Open Source Robotics Foundation, Inc. +// All rights reserved. +// +// Software License Agreement (BSD License 2.0) +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#ifndef RCPPUTILS__JOIN_HPP_ +#define RCPPUTILS__JOIN_HPP_ + +#include +#include +#include +#include + +namespace rcpputils +{ + +/// Join values in a container turned into strings by a given delimiter +/** + * \param[in] container is a collection of values to be turned into string and joined. + * \param[in] delim is a delimiter to join values turned into strings. + * \tparam CharT is the string character type. + * \tparam ValueT is the container value type. + * \tparam AllocatorT is the container allocator type. + * \tparam ContainerT is the container template type. + * \return joined string + */ +template< + typename CharT, typename ValueT, typename AllocatorT, + template class ContainerT> +std::basic_string +join(const ContainerT & container, const CharT * delim) +{ + std::basic_ostringstream s; + std::copy(container.begin(), container.end(), std::ostream_iterator(s, delim)); + std::basic_string result = s.str(); + if (delim) { + result = result.substr(0, result.length() - strlen(delim)); + } + return result; +} + +} // namespace rcpputils + +#endif // RCPPUTILS__JOIN_HPP_ diff --git a/test/test_join.cpp b/test/test_join.cpp new file mode 100644 index 0000000..198bcd0 --- /dev/null +++ b/test/test_join.cpp @@ -0,0 +1,94 @@ +// Copyright 2019 Open Source Robotics Foundation, Inc. +// +// 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 + +#include +#include +#include + +#include "rcpputils/join.hpp" + + +TEST(test_join, join_strings_vector) { + { + const std::vector zero_elements; + EXPECT_EQ("", rcpputils::join(zero_elements, "")); + EXPECT_EQ("", rcpputils::join(zero_elements, ", ")); + } + { + const std::vector one_element{"foo"}; + EXPECT_EQ("foo", rcpputils::join(one_element, "")); + EXPECT_EQ("foo", rcpputils::join(one_element, ", ")); + } + { + const std::vector many_elements{"foo", "bar", "baz"}; + EXPECT_EQ("foobarbaz", rcpputils::join(many_elements, "")); + EXPECT_EQ("foo, bar, baz", rcpputils::join(many_elements, ", ")); + } +} + +TEST(test_join, join_strings_list) { + { + const std::list zero_elements; + EXPECT_EQ("", rcpputils::join(zero_elements, "")); + EXPECT_EQ("", rcpputils::join(zero_elements, ", ")); + } + { + const std::list one_element{"foo"}; + EXPECT_EQ("foo", rcpputils::join(one_element, "")); + EXPECT_EQ("foo", rcpputils::join(one_element, ", ")); + } + { + const std::list many_elements{"foo", "bar", "baz"}; + EXPECT_EQ("foobarbaz", rcpputils::join(many_elements, "")); + EXPECT_EQ("foo, bar, baz", rcpputils::join(many_elements, ", ")); + } +} + +TEST(test_join, join_ints_vector) { + { + const std::vector zero_elements; + EXPECT_EQ("", rcpputils::join(zero_elements, "")); + EXPECT_EQ("", rcpputils::join(zero_elements, ", ")); + } + { + const std::vector one_element{1}; + EXPECT_EQ("1", rcpputils::join(one_element, "")); + EXPECT_EQ("1", rcpputils::join(one_element, ", ")); + } + { + const std::vector many_elements{1, 2, 3}; + EXPECT_EQ("123", rcpputils::join(many_elements, "")); + EXPECT_EQ("1, 2, 3", rcpputils::join(many_elements, ", ")); + } +} + +TEST(test_join, join_ints_list) { + { + const std::list zero_elements; + EXPECT_EQ("", rcpputils::join(zero_elements, "")); + EXPECT_EQ("", rcpputils::join(zero_elements, ", ")); + } + { + const std::list one_element{1}; + EXPECT_EQ("1", rcpputils::join(one_element, "")); + EXPECT_EQ("1", rcpputils::join(one_element, ", ")); + } + { + const std::list many_elements{1, 2, 3}; + EXPECT_EQ("123", rcpputils::join(many_elements, "")); + EXPECT_EQ("1, 2, 3", rcpputils::join(many_elements, ", ")); + } +}