https://github.com/pyzh/borrow
https://github.com/pyzh/borrow
Last synced: over 1 year ago
JSON representation
- Host: GitHub
- URL: https://github.com/pyzh/borrow
- Owner: pyzh
- Created: 2019-01-07T12:09:41.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2017-01-03T07:48:27.000Z (over 9 years ago)
- Last Synced: 2025-01-22T01:41:26.778Z (over 1 year ago)
- Language: C++
- Size: 3.91 KB
- Stars: 0
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.rst
Awesome Lists containing this project
README
======
borrow
======
Constant expressions in C++ are not as constant as you might think. For
example, the following program will cause a compiler error.
.. code:: c++
// example0.cpp
#include "borrow.hpp"
int
main() {
using borrow::ended;
struct $ {
struct Lifetime;
};
static_assert(not ended(${}, 0));
struct $::Lifetime {
struct Ended;
};
static_assert(not ended(${}, 0)); // compiler error here
}
This feature does not seem to be useful at first glance. Thanks to the
brilliant `friend injection techique discovered by Filip Roséen`__ , stateful
metaprogramming has become feasible in C++.
.. __: http://b.atch.se/posts/non-constant-constant-expressions/
Rust, a promising rival to C++, is famed for its borrow checker. With stateful
metaprogramming, we can have the same mechanism implemented at compile-time in
C++.
.. code:: c++
// example1.cpp
#include
#include
#include
#include "borrow.hpp"
template
struct Container {
char buf[sizeof(T)];
void
write(T&& item) {
T *ptr = static_cast(static_cast(buf));
new (ptr) T(::std::move(item));
}
T
read() {
T *ptr = static_cast(static_cast(buf));
T item = ::std::move(*ptr);
ptr->~T();
return item;
}
T&
get() {
T *ptr = static_cast(static_cast(buf));
return *ptr;
}
T const&
get() const {
T *ptr = static_cast(static_cast(buf));
return *ptr;
}
};
template::type>
auto
get(::borrow::BorrowPtr,$> ptr) {
return ::borrow::BorrowPtr { (*ptr).get() };
}
int
main() {
auto c = Container {};
c.write(0);
BEGIN_LIFETIME($);
auto p = ::borrow::borrow_mut<$>(c);
BEGIN_LIFETIME($1);
auto p1 = ::borrow::borrow_mut<$1>(p);
auto p2 = get(p1);
*p2 = 1;
END_LIFETIME($1);
*p2; // compiler error here
END_LIFETIME($);
}