Skip to content

Instantly share code, notes, and snippets.

@komori-n
Created October 11, 2020 05:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save komori-n/c8b8a4e0b1eaf7ad1623b63e50d94561 to your computer and use it in GitHub Desktop.
Save komori-n/c8b8a4e0b1eaf7ad1623b63e50d94561 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <functional>
class Undefined_class;
union Nocopy_types {
void* a;
const void* b;
void (*c)();
void (Undefined_class::*d)();
};
static constexpr size_t kMaxSize = sizeof(Nocopy_types);
static constexpr size_t kMaxAlign = sizeof(Nocopy_types);
template <typename T>
struct StoredLocally {
static const bool value = (
std::__is_location_invariant<T>::value &&
sizeof(T) <= kMaxSize &&
__alignof__(T) <= kMaxAlign &&
kMaxAlign % __alignof__(T) == 0);
};
template <typename T>
bool stored_locally(T t) {
return StoredLocally<T>::value;
}
template <size_t N>
struct DummyData_t {
char data[N];
};
template <size_t N>
struct DummyData : public DummyData_t<N> {
static_assert(sizeof(DummyData_t<N>) == N);
};
void hoge(void) {}
struct Fuga {
void piyo(void) {}
};
template <size_t N>
struct Fn {
DummyData<N> dummy;
void operator()(void) {}
};
struct Gn {
Gn& operator=(const Gn& gn) { return *this; };
void operator()(void) {}
};
int main(void) {
std::cout << sizeof(void*) << std::endl; // 8
std::cout << sizeof(const void*) << std::endl; // 8
std::cout << sizeof(void(*)()) << std::endl; // 8
std::cout << sizeof(void (Undefined_class::*)()) << std::endl; // 16
std::cout << sizeof(Nocopy_types) << std::endl; // 16
// 関数ポインタ
std::cout << stored_locally(hoge) << std::endl; // true
// メンバ関数ポインタ
std::cout << stored_locally(&Fuga::piyo) << std::endl; // true
// ラムダ式
std::cout << stored_locally([](){}) << std::endl; // true (sizeof(fn)==1だから)
std::cout << stored_locally([a=DummyData<16>()](){}) << std::endl; // true (sizeof(fn)==16だから)
std::cout << stored_locally([a=DummyData<17>()](){}) << std::endl; // false(sizeof(fn)==17だから)
// 関数オブジェクト
std::cout << stored_locally(Fn<16>()) << std::endl; // true (sizeof(fn)==16だから)
std::cout << stored_locally(Fn<17>()) << std::endl; // false(sizeof(fn)==17だから)
std::cout << stored_locally(Gn()) << std::endl; // false(trivially_copyableではないから)
std::cout << sizeof(std::function<int(int,int,int,int,int)>) << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment