Skip to content

Commit fc11216

Browse files
committed
0.22: New: ptr_to_string(ptr)
1 parent f503334 commit fc11216

2 files changed

Lines changed: 69 additions & 1 deletion

File tree

‎src/VERSION‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.21.0
1+
0.22.0

‎src/str/ptr_to_string.cpp‎

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// 0.1.1
2+
// C++20 for fn(auto)
3+
4+
#include <string>
5+
#include <charconv> // to_chars, C++17
6+
#include <cstdint> // uintptr_t
7+
#include <cassert>
8+
//#include <type_traits> // Uncomment if you accept the reality that you've
9+
// already paid for those `requires`es below anyway
10+
// and now you want to enable them after all, because
11+
// <type_traits> absolutely *has* been pulled in a
12+
// few times already... ;)
13+
14+
//----------------------------------------------------------------------------
15+
//
16+
// NOTE: Doesn't 0-pad the result, lengths vary!
17+
//
18+
// We need a template for also accepting non-object (i.e. function) pointers!
19+
//static_assert(std::is_convertible_v<void(*)(), void*>); // MSVC accepts it, but non-std!
20+
inline std::string ptr_to_string(auto* p) // - `auto` needed (and therefore C++20), because
21+
// void* wouldn't pick up function ptrs
22+
// - but not just `auto`: auto* to require pointers
23+
// - but not `const auto*`: templ. ded. covers that!
24+
// - `inline` is optional here, as this is already a template
25+
// With just plain `auto p` above, you could also do this, if willing to include <type_traits>:
26+
// requires (std::is_pointer_v<decltype(p)>
27+
// || std::is_null_pointer_v<decltype(p)>) // add this if you want to accept nullptr!
28+
{
29+
using namespace std; // everything's std in here
30+
31+
char buf[sizeof(uintptr_t) * 2]; // - 2 hex chars per byte
32+
// - EOS not needed for the string ctor
33+
// - zeroing not needed for to_chars
34+
auto [past_last, ec] = to_chars(buf,
35+
buf + sizeof(buf), // or end(buf), but you'd need #include <iterator> for that, technically
36+
reinterpret_cast<uintptr_t>(p), // fn* -> uniptr is condit. supported: if compiles, it's legit!
37+
16
38+
);
39+
assert(ec == errc{}); // to_chars should never fail in this case!
40+
return string(buf, past_last);
41+
};
42+
// This is to support nullptr with the auto* signature above (and disabled `requires`):
43+
inline auto ptr_to_string(decltype(nullptr)) { return ptr_to_string((void*)0); }
44+
45+
46+
#ifdef UNIT_TEST
47+
#include <iostream>
48+
49+
int main()
50+
{
51+
// Objects:
52+
std::cout << ptr_to_string(&std::cin) << std::endl;
53+
// Also null:
54+
std::cout << ptr_to_string(nullptr) << std::endl;
55+
std::cout << ptr_to_string((void*)0) << std::endl;
56+
57+
// Functions:
58+
//std::cout << ptr_to_string(main) << std::endl; // Well, main is sacred, can't utter its name! :-o
59+
//std::cout << ptr_to_string(ptr_to_string) << std::endl; // Umm, and this is a template, and an overload set now... :)
60+
// Well, fuckit:
61+
std::cout << ptr_to_string(+[]{}) << std::endl;
62+
63+
// Wrong arg. types:
64+
//std::cout << ptr_to_string(0) << std::endl;
65+
//std::cout << ptr_to_string(1) << std::endl;
66+
//std::cout << ptr_to_string(std::cin) << std::endl;
67+
}
68+
#endif // UNIT_TEST

0 commit comments

Comments
 (0)