公众号
qq群 手机qq点击进入
RSS https://github.com/wanghenshui/cppweeklynews/releases.atom
欢迎投稿,推荐或自荐文章/软件/资源等
126期代码抄错,这里指正一下
consteval auto as_constant(auto value) {
return value;
}
constexpr int Calc(int x) { return 4 * x; }
// consteval int Calc(int x) { return 4 * x; }
int main() {
auto res = Calc(2);
// auto res = as_constant(Calc(2));
++res;
res = Calc(res); //编译不过
return res;
}
之前抄成consteval了,这里感谢 @fanenr 指正
另外感谢 不语
汪总
赞助
标准委员会动态/ide/编译器信息放在这里
八月提案 https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/#mailing2023-08
编译器信息最新动态推荐关注hellogcc公众号 上周更新 2023-08-16 第215期
本周没更新
cppcon 2023开始卖票
代码review
memset用错,看不出问题的罚深蹲五个
int64_t FileList::VMProcess(int OpCode,
void *vParam,
int64_t iParam)
{
....
PluginInfo *PInfo = (PluginInfo *)vParam;
memset(PInfo, 0, sizeof(PInfo));
....
}
里面还有各种越界/复制粘贴错误。懒得贴了
一段简单的代码
static constexpr std::size_t kLineSize = (1 << 23); // 8MB
struct Line {
char _data[kLineSize];
std::mutex _mtx;
std::atomic<std::size_t> _size = 0;
};
auto line = std::make_shared<Line>();
查perf图有莫名其妙的memset
哈哈。之前咱们也提到过,数组,调用make_xx会帮你初始化,所以有memset
除了标准库给的make_unique_for_overwrite这种玩意之外,也可以定制构造函数,构造函数为空,啥也不做就行了
这个文章的标题不对了,这个其实和shared_ptr没啥关系,unique_ptr也有,本质是调用构造函数的问题,默认构造函数的问题
std::optional
in C++23 std::optional<UserProfile> fetchFromCache(int userId);
std::optional<UserProfile> fetchFromServer(int userId);
std::optional<int> extractAge(const UserProfile& profile);
int main() {
const int userId = 12345;
const auto ageNext = fetchFromCache(userId)
.or_else([&]() { return fetchFromServer(userId); })
.and_then(extractAge)
.transform([](int age) { return age + 1; });
if (ageNext)
cout << format("Next year, the user will be {} years old", *ageNext);
else
cout << "Failed to determine user's age.\n";
}
就是介绍这几个新api的用法
其实看一下代码就懂了
还是老生常谈的 char*歧义,导致不能充分优化,要么就restrict,要么就换成 别的类型来操作
别的类型,可以是你自己封装一下char,也可以是char8_t,_BitInt(8) 别用vector
以下两篇文章来自CppMore,大家也可以关注cppMore公众号
用fixed_stding做类型tag,tag有必要这么花哨吗
手把手教你熟悉monad,熟悉optional/expect/range,读者反馈讲的特好
其实就是状态链式流转,不知道为啥链式调用看起来很叼
直接看代码吧,其实c++11的东西
template <typename T>
struct Singleton {
Singleton() = default;
~Singleton() = default;
// Delete the copy and move constructors
Singleton(const Singleton &) = delete;
Singleton &operator=(const Singleton &) = delete;
Singleton(Singleton &&) = delete;
Singleton &operator=(Singleton &&) = delete;
static T &get() {
static T instance{};
return instance;
}
};
fixed_string怎么连接????
硬拷呗
template <typename char_type, std::size_t N, std::size_t M>
constexpr auto concat_fixed_string(basic_fixed_string<char_type, N> l,
basic_fixed_string<char_type, M> r) noexcept {
basic_fixed_string<char_type, N + M> result;
auto it{ std::copy(l.begin(), l.end(), result.begin()) };
it = std::copy(r.begin(), r.end(), it);
*it = {};
return result;
}
代码来自 https://github.com/arturbac/small_vectors/blob/master/include/coll/basic_fixed_string.h
或者体验这个 c++20的版本 https://godbolt.org/z/Gdfnsf8Pa 也是硬来
看个乐
介绍shared_ptr各种转换之后的内存问题,控制块和实际内存块占用关系/判定
我的评价是就当不知道这个事儿吧,看了迷糊
看得我眼睛疼
利用boost::mp11来做tag
#include <boost/mp11/algorithm.hpp>
#include <boost/mp11/list.hpp>
#include <type_traits>
template<typename T,typename... Qualifiers>
struct access: T
{
using qualifier_list=boost::mp11::mp_list<Qualifiers...>;
using T::T;
};
template<typename T, typename... Qualifiers>
concept qualified =
(boost::mp11::mp_contains<
typename std::remove_cvref_t<T>::qualifier_list,
Qualifiers>::value && ...);
// some qualifiers
struct mut;
struct synchronized;
template<typename T>
concept is_mut = qualified<T, mut>;
template<typename T>
concept is_synchronized = qualified<T, synchronized>;
struct X
{
void foo() {}
template<is_mut Self>
void bar(this Self&&) {}
template<is_synchronized Self>
void baz(this Self&&) {}
template<typename Self>
void qux(this Self&&)
requires qualified<Self, mut, synchronized>
{}
};
int main()
{
access<X, mut> x;
x.foo();
x.bar();
x.baz(); // error: associated constraints are not satisfied
x.qux(); // error: associated constraints are not satisfied
X y;
x.foo();
y.bar(); // error: associated constraints are not satisfied
access<X, mut, synchronized> z;
z.bar();
z.baz();
z.qux();
}
我觉得tag挺简单的,怎么看大家都实现的这么复杂
SIMD时间
常规
unsigned char byte = data[pos];
if ((byte & 0x80) == 0) { // if ASCII
// will generate one UTF-8 byte
*utf8_output++ = (char)(byte);
pos++;
} else {
// will generate two UTF-8 bytes
*utf8_output++ = (char)((byte >> 6) | 0b11000000);
*utf8_output++ = (char)((byte & 0b111111) | 0b10000000);
pos++;
}
SIMD
__mmask32 nonascii = _mm256_movepi8_mask(input);
__mmask64 sixth =
_mm512_cmpge_epu8_mask(input, _mm512_set1_epi8(-64));
const uint64_t alternate_bits = UINT64_C(0x5555555555555555);
uint64_t ascii = ~nonascii;
uint64_t maskA = ~_pdep_u64(ascii, alternate_bits);
uint64_t maskB = ~_pdep_u64(ascii>>32, alternate_bits);
// interleave bytes from top and bottom halves (abcd...ABCD -> aAbBcCdD)
__m512i input_interleaved = _mm512_permutexvar_epi8(_mm512_set_epi32(
0x3f1f3e1e, 0x3d1d3c1c, 0x3b1b3a1a, 0x39193818,
0x37173616, 0x35153414, 0x33133212, 0x31113010,
0x2f0f2e0e, 0x2d0d2c0c, 0x2b0b2a0a, 0x29092808,
0x27072606, 0x25052404, 0x23032202, 0x21012000
), input);
// double size of each byte, and insert the leading byte
__m512i outputA = _mm512_shldi_epi16(input_interleaved, _mm512_set1_epi8(-62), 8);
outputA = _mm512_mask_add_epi16(outputA, (__mmask32)sixth, outputA, _mm512_set1_epi16(1 - 0x4000));
__m512i leadingB = _mm512_mask_blend_epi16((__mmask32)(sixth>>32), _mm512_set1_epi16(0x00c2), _mm512_set1_epi16(0x40c3));
__m512i outputB = _mm512_ternarylogic_epi32(input_interleaved, leadingB, _mm512_set1_epi16((short)0xff00), (240 & 170) ^ 204); // (input_interleaved & 0xff00) ^ leadingB
// prune redundant bytes
outputA = _mm512_maskz_compress_epi8(maskA, outputA);
outputB = _mm512_maskz_compress_epi8(maskB, outputB);
眼睛花了
代码在这里 https://github.com/lemire/Code-used-on-Daniel-Lemire-s-blog/tree/master/2023/08/18
太长了没看完。周末总结一下
如果有疑问评论最好在上面链接到评论区里评论,这样方便搜索,微信公众号有点封闭/知乎吞评论