Skip to content

Commit

Permalink
constant_string_view tests and fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
anarthal committed Feb 6, 2024
1 parent 3d9f426 commit 9f2081a
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 4 deletions.
39 changes: 35 additions & 4 deletions include/boost/mysql/constant_string_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@

#include <type_traits>

#ifdef __cpp_lib_string_view
#include <string_view>
#endif

namespace boost {
namespace mysql {

Expand All @@ -37,15 +41,40 @@ class constant_string_view
friend BOOST_CXX14_CONSTEXPR inline constant_string_view runtime(string_view) noexcept;

public:
/**
* \brief Consteval constructor.
* \details
* Constructs a \ref string_view from the passed argument.
* \n
* This function is `consteval`: it results in a compile-time error
* if the passed value is not known at compile-time. You can bypass
* this check using the \ref runtime function. This check works only
* for C++20 and above. No check is performed for lower C++ standard versions.
* \n
* This constructor is only considered if a \ref string_view can be constructed
* from the passed value.
*
* \par Exception safety
* No-throw guarantee.
*
* \par Object lifetimes
* Ownership is not transferred to the constructed object. As with `string_view`,
* the user is responsible for keeping the original character buffer alive.
*/
template <
class T
#ifndef BOOST_MYSQL_DOXYGEN
,
class = typename std::enable_if<std::is_convertible<const T&, string_view>::value>::type
#endif
>
BOOST_MYSQL_CONSTEVAL constant_string_view(const T& value) noexcept : impl_(value)
{
}

#ifdef __cpp_lib_string_view
/**
* \brief Consteval constructor.
* \brief Consteval constructor from `std::sting_view`.
* \details
* Constructs a \ref string_view from the passed argument.
* \n
Expand All @@ -54,8 +83,8 @@ class constant_string_view
* this check using the \ref runtime function. This check works only
* for C++20 and above. No check is performed for lower C++ standard versions.
* \n
* This constructor is only considered if a \ref string_view can be constructed
* from the passed value.
* \ref string_view's constructor from `std::string_view` is not `constexpr`.
* This constructor workaround this limitation.
*
* \par Exception safety
* No-throw guarantee.
Expand All @@ -64,9 +93,11 @@ class constant_string_view
* Ownership is not transferred to the constructed object. As with `string_view`,
* the user is responsible for keeping the original character buffer alive.
*/
BOOST_MYSQL_CONSTEVAL constant_string_view(const T& value) noexcept : impl_(value)
BOOST_MYSQL_CONSTEVAL constant_string_view(std::string_view value) noexcept
: impl_(value.data(), value.size())
{
}
#endif

/**
* \brief Retrieves the underlying string view.
Expand Down
1 change: 1 addition & 0 deletions test/unit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ add_executable(
test/connection_pool.cpp
test/character_set.cpp
test/escape_string.cpp
test/constant_string_view.cpp
test/format_sql.cpp
)
target_include_directories(
Expand Down
1 change: 1 addition & 0 deletions test/unit/Jamfile
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ run
test/connection_pool.cpp
test/character_set.cpp
test/escape_string.cpp
test/constant_string_view.cpp
test/format_sql.cpp

: requirements
Expand Down
101 changes: 101 additions & 0 deletions test/unit/test/constant_string_view.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
//
// Copyright (c) 2019-2023 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#include <boost/mysql/constant_string_view.hpp>
#include <boost/mysql/string_view.hpp>

#include <boost/mysql/detail/config.hpp>

#include <boost/test/unit_test.hpp>

#ifdef __cpp_lib_string_view
#include <string_view>
#endif

using namespace boost::mysql;

BOOST_AUTO_TEST_SUITE(test_constant_string_view)

// Use constant_string_view in a regular, runtime function. This mimics real use.
string_view f(constant_string_view arg) noexcept { return arg.get(); }

// Checks that SFINAE in constant_string_view constructor works.
int f(int arg) noexcept { return arg; }

#ifndef BOOST_NO_CXX14_CONSTEXPR
BOOST_AUTO_TEST_CASE(ctor_string_view)
{
constexpr string_view s("abcd", 4); // ctor from const char* is C++17 constexpr because traits
BOOST_TEST(f(s) == "abcd");
}
#endif

#ifdef __cpp_lib_string_view
BOOST_AUTO_TEST_CASE(ctor_std_string_view)
{
constexpr std::string_view s = "abcd";
BOOST_TEST(f(s) == "abcd");
}
#endif

BOOST_AUTO_TEST_CASE(ctor_c_string)
{
constexpr const char* s = "abcd";
BOOST_TEST(f(s) == "abcd");
}

BOOST_AUTO_TEST_CASE(ctor_string_literal) { BOOST_TEST(f("abcd") == "abcd"); }

BOOST_AUTO_TEST_CASE(constructor_sfinae)
{
// This wouldn't compile if we blindly accepted any T as argument for constant_string_view ctor
BOOST_TEST(f(42) == 42);
}

BOOST_AUTO_TEST_CASE(copy_move)
{
// Copy/move operations don't conflict with templated constructors
const constant_string_view s1{"abcd"};
constant_string_view s2(s1);
constant_string_view s3(std::move(s2));
s2 = s1;
s3 = std::move(s2);
}

BOOST_AUTO_TEST_CASE(runtime_c_str)
{
const char* s = "abc";
BOOST_TEST(f(runtime(s)) == "abc");
}

BOOST_AUTO_TEST_CASE(runtime_string_view)
{
string_view s = "abc";
BOOST_TEST(f(runtime(s)) == "abc");
}

BOOST_AUTO_TEST_CASE(runtime_string)
{
std::string s = "abc";
BOOST_TEST(f(runtime(s)) == "abc");
}

#ifdef __cpp_lib_string_view
BOOST_AUTO_TEST_CASE(runtime_std_string_view)
{
std::string_view s = "abc";
BOOST_TEST(f(runtime(s)) == "abc");
}
#endif

// Constexpr-ness checks
#ifndef BOOST_NO_CXX14_CONSTEXPR
static constexpr string_view abcd_str("abcd", 4); // ctor from const char* is C++17 constexpr because traits
static_assert(constant_string_view(abcd_str).get() == abcd_str);
#endif

BOOST_AUTO_TEST_SUITE_END()

0 comments on commit 9f2081a

Please sign in to comment.