Skip to content

Commit

Permalink
Add specializations for more ATL/MFC strings
Browse files Browse the repository at this point in the history
* CSimpleStringT, CFixedStringT

* For C++20 - any string derived from CSimpleStringT
  • Loading branch information
rmisev committed Oct 12, 2024
1 parent 3b4ae67 commit 5c76c89
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 5 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ if (UPA_BUILD_TESTS)
test/test-url.cpp
test/test-url-port.cpp
test/test-url-setters.cpp
test/test-url_for_.cpp
test/test-url_host.cpp
test/test-url_percent_encode.cpp
test/test-url_search_params.cpp
Expand Down
45 changes: 40 additions & 5 deletions include/upa/url_for_atl.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,55 @@
#ifndef UPA_URL_FOR_ATL_H
#define UPA_URL_FOR_ATL_H

#include "config.h"
#include "url.h" // IWYU pragma: export
#include <cstringt.h>
#include <atlsimpstr.h>
#ifdef UPA_CPP_20
# include <concepts>
#else
# include <cstringt.h>
#endif

namespace upa {

template<typename CharT, class StringTraits>
struct str_arg_char<ATL::CStringT<CharT, StringTraits>> {
using type = CharT;
template<class StrT>
struct str_arg_char_for_atl {
using type = typename StrT::XCHAR;

static str_arg<CharT> to_str_arg(const ATL::CStringT<CharT, StringTraits>& str) {
static str_arg<type> to_str_arg(const StrT& str) {
return { str.GetString(), static_cast<std::ptrdiff_t>(str.GetLength()) };
}
};

#ifdef UPA_CPP_20

// CStringT and CFixedStringT are derived from CSimpleStringT
template<class StrT>
concept derived_from_CSimpleString =
std::derived_from<StrT, ATL::CSimpleStringT<char, true>> ||
std::derived_from<StrT, ATL::CSimpleStringT<wchar_t, true>> ||
std::derived_from<StrT, ATL::CSimpleStringT<char, false>> ||
std::derived_from<StrT, ATL::CSimpleStringT<wchar_t, false>>;

template<derived_from_CSimpleString StrT>
struct str_arg_char<StrT> : public str_arg_char_for_atl<StrT> {};

#else // UPA_CPP_20

template<typename CharT, bool mfcdll>
struct str_arg_char<ATL::CSimpleStringT<CharT, mfcdll>> :
public str_arg_char_for_atl<ATL::CSimpleStringT<CharT, mfcdll>> {};

template<typename CharT, class StringTraits>
struct str_arg_char<ATL::CStringT<CharT, StringTraits>> :
public str_arg_char_for_atl<ATL::CStringT<CharT, StringTraits>> {};

template<class StrT, int nChars>
struct str_arg_char<ATL::CFixedStringT<StrT, nChars>> :
public str_arg_char_for_atl<ATL::CFixedStringT<StrT, nChars>> {};

#endif // UPA_CPP_20

} // namespace upa

#endif // UPA_URL_FOR_ATL_H
44 changes: 44 additions & 0 deletions test/test-url_for_.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright 2024 Rimas Misevičius
// Distributed under the BSD-style license that can be
// found in the LICENSE file.
//

#include "doctest-main.h"

#ifdef _MSC_VER
# define UPA_TEST_URL_FOR_ATL
# include "upa/url_for_atl.h"
# include <atlsimpstr.h>
# include <atlstr.h>
# include <cstringt.h>
#endif

#ifdef UPA_TEST_URL_FOR_ATL

TEST_CASE("ATL::CSimpleStringA input") {
ATL::CStringA basestr;

ATL::CSimpleStringA str_input("http://host/", basestr.GetManager());
upa::url url{ str_input };
CHECK(url.href() == "http://host/");
}

TEST_CASE("ATL::CSimpleStringW input") {
ATL::CStringW basestr;

ATL::CSimpleStringW str_input(L"http://host/", basestr.GetManager());
upa::url url{ str_input };
CHECK(url.href() == "http://host/");
}

TEST_CASE_TEMPLATE_DEFINE("ATL string input", StrT, test_url_for_atl) {
StrT str_input("http://host/");
upa::url url{ str_input };
CHECK(url.href() == "http://host/");
}

TEST_CASE_TEMPLATE_INVOKE(test_url_for_atl,
ATL::CStringA, ATL::CFixedStringT<ATL::CStringA, 16>,
ATL::CStringW, ATL::CFixedStringT<ATL::CStringW, 16>);

#endif // UPA_TEST_URL_FOR_ATL

0 comments on commit 5c76c89

Please sign in to comment.