Last active
April 12, 2017 21:28
-
-
Save th0rex/d7f2aeab6886581f512c126dd5df32d6 to your computer and use it in GitHub Desktop.
linq stuff
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <algorithm> | |
#include <experimental/optional> | |
#include <iostream> | |
#include <vector> | |
#include <random> | |
using std::experimental::make_optional; | |
using std::experimental::optional; | |
template <class... F> | |
class Overload : public F... { | |
public: | |
Overload(F&&... f) : F{std::forward<F>(f)}... {} | |
}; | |
template <class... F> | |
auto make_overload(F&&... f) { | |
return Overload<F...>{std::forward<F>(f)...}; | |
} | |
template <class T> | |
struct is_option { | |
constexpr static bool value = false; | |
}; | |
template <class T> | |
struct is_option<optional<T>> { | |
constexpr static bool value = true; | |
}; | |
template <class F> | |
auto make_enumerable(F&& f); | |
template <class F> | |
class IEnumerable { | |
F _f; | |
public: | |
IEnumerable(F&& f) : _f{std::forward<F>(f)} {} | |
template <class U> | |
auto map(U&& u) { | |
return make_enumerable(make_overload( | |
[ t = std::move(*this), u = std::forward<U>(u) ](auto&& a) | |
->std::enable_if_t< | |
is_option<decltype(a)>::value, | |
optional<decltype(u(*_f(std::forward<decltype(a)>(a))))>> { | |
if (a) { | |
auto b = t._f(std::forward<decltype(a)>(a)); | |
if (!b) { | |
return optional<decltype(u(std::move(*b)))>{}; | |
} | |
return make_optional(u(std::move(*b))); | |
} else { | |
return optional<decltype( | |
u(*t._f(std::forward<decltype(a)>(a))))>{}; | |
} | |
}, | |
[ t = std::move(*this), u = std::forward<U>(u) ](auto&& a) | |
->std::enable_if_t< | |
!is_option<decltype(a)>::value, | |
optional<decltype(u(*_f(std::forward<decltype(a)>(a))))>> { | |
auto b = t._f(std::forward<decltype(a)>(a)); | |
if (b) { | |
return (u(std::move(*b))); | |
} | |
return optional<decltype(u(std::move(*b)))>{}; | |
})); | |
} | |
template <class T, template <class, class = std::allocator<T>> class C> | |
auto operator()(C<T> container) { | |
using A = typename std::result_of_t<F(T)>::value_type; | |
C<A, std::allocator<A>> ret; | |
for (auto& e : container) { | |
auto r = _f(e); | |
if (r) { | |
ret.push_back(std::move(*r)); | |
} | |
} | |
return ret; | |
} | |
}; | |
template <class F> | |
auto make_enumerable(F&& f) { | |
return IEnumerable<F>{std::forward<F>(f)}; | |
} | |
auto linq() { | |
return make_enumerable( | |
[](auto&& a) { return make_optional(std::forward<decltype(a)>(a)); }); | |
} | |
auto random_vec() { | |
std::mt19937 rand; | |
std::uniform_int_distribution<int> dist(1, 100); | |
std::vector<int> ret; | |
for(auto i = 0; i < 10; ++i) { | |
ret.push_back(dist(rand)); | |
} | |
return ret; | |
} | |
int main() { | |
auto i = random_vec(); | |
auto mapper = linq().map([](auto&& i) { return i + 1; }).map([](auto&& j) { | |
return j * 2; | |
}); | |
auto result = mapper(i); | |
for (const auto& e : result) { | |
std::cout << e << std::endl; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
int __cdecl main(int argc, const char **argv, const char **envp) | |
{ | |
char *v3; // ebx@1 | |
void *v4; // edi@1 | |
size_t v5; // esi@1 | |
unsigned int v6; // ebp@1 | |
char *v7; // edx@4 | |
int v8; // ebp@5 | |
int v9; // ecx@5 | |
signed int v10; // ebx@8 | |
signed int v11; // edi@8 | |
signed int v12; // eax@8 | |
unsigned int v13; // esi@10 | |
_DWORD *v14; // edi@14 | |
size_t n; // ST08_4@18 | |
char *v16; // ebx@18 | |
char *v17; // esi@24 | |
char *v18; // edi@26 | |
std::ostream *v19; // eax@27 | |
std::ostream *v20; // esi@27 | |
int v21; // eax@27 | |
int v22; // ebp@27 | |
char v23; // al@29 | |
std::ostream *v24; // eax@31 | |
int v26; // edi@39 | |
char *v27; // [sp+18h] [bp-34h]@0 | |
const void *v28; // [sp+1Ch] [bp-30h]@1 | |
void *v29; // [sp+20h] [bp-2Ch]@0 | |
int v30; // [sp+24h] [bp-28h]@5 | |
signed int v31; // [sp+28h] [bp-24h]@8 | |
int v32; // [sp+2Ch] [bp-20h]@8 | |
void *v33; // [sp+30h] [bp-1Ch]@1 | |
int v34; // [sp+34h] [bp-18h]@1 | |
random_vec(); | |
v3 = 0; | |
v4 = 0; | |
v5 = v34 - (_DWORD)v33; | |
v28 = v33; | |
v6 = (v34 - (signed int)v33) >> 2; | |
if ( v6 ) | |
{ | |
if ( v6 >= 0x40000000 ) | |
goto LABEL_39; | |
v4 = (void *)operator new(v34 - (_DWORD)v33); | |
} | |
v7 = 0; | |
if ( v6 ) | |
{ | |
memmove(v4, v28, v5); | |
v30 = 4 * v6; | |
v8 = 0; | |
v9 = 0; | |
v3 = 0; | |
v7 = 0; | |
v29 = v4; | |
do | |
{ | |
if ( v3 == (char *)v9 ) | |
{ | |
v10 = v3 - v7; | |
v32 = 2 * *(_DWORD *)((char *)v4 + v8) + 2; | |
v11 = v10 >> 2; | |
v12 = v10 >> 2; | |
v31 = v10 >> 2; | |
if ( !(v10 >> 2) ) | |
v12 = 1; | |
v13 = v12 + v11; | |
if ( (unsigned int)(v12 + v11) > 0x3FFFFFFF ) | |
v13 = 0x3FFFFFFF; | |
if ( __CFADD__(v11, v12) ) | |
v13 = 0x3FFFFFFF; | |
v14 = 0; | |
if ( v13 ) | |
{ | |
v27 = v7; | |
if ( v13 >= 0x40000000 ) | |
goto LABEL_38; | |
v14 = (_DWORD *)operator new(4 * v13); | |
v7 = v27; | |
} | |
v14[v31] = v32; | |
if ( v31 ) | |
{ | |
n = v10; | |
v16 = v7; | |
memmove(v14, v7, n); | |
v7 = v16; | |
} | |
if ( v7 ) | |
operator delete(v7); | |
v9 = (int)&v14[v13]; | |
v7 = (char *)v14; | |
v3 = (char *)&v14[v31]; | |
v4 = v29; | |
} | |
else | |
{ | |
*(_DWORD *)v3 = 2 * *(_DWORD *)((char *)v4 + v8) + 2; | |
} | |
v8 += 4; | |
v3 += 4; | |
} | |
while ( v30 != v8 ); | |
} | |
if ( v4 ) | |
{ | |
v17 = v7; | |
operator delete(v4); | |
v7 = v17; | |
} | |
v27 = v7; | |
if ( v7 != v3 ) | |
{ | |
v18 = v7; | |
while ( 1 ) | |
{ | |
v19 = (std::ostream *)std::ostream::operator<<(&std::cout, *(_DWORD *)v18); | |
v20 = v19; | |
v21 = *(_DWORD *)(*(_DWORD *)v19 - 12); | |
v22 = *(_DWORD *)((char *)v20 + v21 + 124); | |
if ( !v22 ) | |
break; | |
if ( *(_BYTE *)(v22 + 28) ) | |
{ | |
v23 = *(_BYTE *)(v22 + 39); | |
} | |
else | |
{ | |
std::ctype<char>::_M_widen_init(*(_DWORD *)((char *)v20 + v21 + 124)); | |
v23 = (*(int (__cdecl **)(int, signed int))(*(_DWORD *)v22 + 24))(v22, 10); | |
} | |
v24 = (std::ostream *)std::ostream::put(v20, v23); | |
std::ostream::flush(v24); | |
v18 += 4; | |
if ( v3 == v18 ) | |
goto LABEL_32; | |
} | |
std::__throw_bad_cast(); | |
LABEL_38: | |
std::__throw_bad_alloc(); | |
LABEL_39: | |
v26 = std::__throw_bad_alloc(); | |
if ( v27 ) | |
operator delete(v27); | |
if ( v29 ) | |
operator delete(v29); | |
if ( v28 ) | |
operator delete((void *)v28); | |
_Unwind_Resume(v26); | |
} | |
LABEL_32: | |
if ( v27 ) | |
operator delete(v27); | |
if ( v33 ) | |
operator delete(v33); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cppint __cdecl main(int argc, const char **argv, const char **envp) | |
{ | |
void *v3; // r15@1 | |
unsigned __int64 v4; // rbx@1 | |
const char **v5; // r13@4 | |
signed __int64 v6; // rbx@5 | |
__int64 v7; // rbp@5 | |
signed __int64 v8; // rcx@5 | |
int v9; // er14@6 | |
signed __int64 v10; // r13@8 | |
signed __int64 v11; // r12@8 | |
signed __int64 v12; // rax@8 | |
unsigned __int64 v13; // r15@10 | |
_DWORD *v14; // rbx@14 | |
const char **v15; // r14@25 | |
const char **v16; // rbp@26 | |
std::ostream *v17; // rax@27 | |
std::ostream *v18; // r12@27 | |
__int64 v19; // rax@27 | |
__int64 v20; // rbx@27 | |
char v21; // al@29 | |
std::ostream *v22; // rax@31 | |
__int64 v24; // rbx@39 | |
void *v25; // [sp+8h] [bp-60h]@0 | |
const char **src; // [sp+10h] [bp-58h]@0 | |
signed __int64 v27; // [sp+18h] [bp-50h]@5 | |
const void *v28; // [sp+20h] [bp-48h]@0 | |
__int64 v29; // [sp+28h] [bp-40h]@0 | |
random_vec(); | |
v3 = 0LL; | |
v4 = (v29 - (signed __int64)v28) >> 2; | |
if ( v4 ) | |
{ | |
if ( v4 > 0x3FFFFFFFFFFFFFFFLL ) | |
goto LABEL_39; | |
v3 = (void *)operator new(v29 - (_QWORD)v28); | |
} | |
argv = 0LL; | |
v5 = 0LL; | |
if ( v4 ) | |
{ | |
memmove(v3, v28, v29 - (_QWORD)v28); | |
v6 = 4 * v4; | |
v7 = 0LL; | |
v8 = 0LL; | |
v5 = 0LL; | |
argv = 0LL; | |
v25 = v3; | |
v27 = v6; | |
do | |
{ | |
v9 = 2 * *(_DWORD *)((char *)v3 + v7) + 2; | |
if ( v5 == (const char **)v8 ) | |
{ | |
v10 = (char *)v5 - (char *)argv; | |
v11 = v10 >> 2; | |
v12 = v10 >> 2; | |
if ( !(v10 >> 2) ) | |
v12 = 1LL; | |
v13 = v12 + v11; | |
if ( (unsigned __int64)(v12 + v11) > 0x3FFFFFFFFFFFFFFFLL ) | |
v13 = 0x3FFFFFFFFFFFFFFFLL; | |
if ( __CFADD__(v11, v12) ) | |
v13 = 0x3FFFFFFFFFFFFFFFLL; | |
v14 = 0LL; | |
if ( v13 ) | |
{ | |
src = argv; | |
if ( v13 > 0x3FFFFFFFFFFFFFFFLL ) | |
goto LABEL_38; | |
v14 = (_DWORD *)operator new(4 * v13); | |
} | |
v14[v11] = v9; | |
if ( v11 ) | |
memmove(v14, argv, v10); | |
if ( argv ) | |
operator delete(argv); | |
v5 = (const char **)&v14[v11]; | |
v8 = (signed __int64)&v14[v13]; | |
argv = (const char **)v14; | |
v3 = v25; | |
v6 = v27; | |
} | |
else | |
{ | |
*(_DWORD *)v5 = v9; | |
} | |
v5 = (const char **)((char *)v5 + 4); | |
v7 += 4LL; | |
} | |
while ( v6 != v7 ); | |
} | |
if ( v3 ) | |
operator delete(v3); | |
v15 = argv; | |
if ( argv != v5 ) | |
{ | |
v16 = argv; | |
while ( 1 ) | |
{ | |
argv = (const char **)*(_DWORD *)v16; | |
LODWORD(v17) = std::ostream::operator<<(&std::cout, argv); | |
v18 = v17; | |
v19 = *(_QWORD *)(*(_QWORD *)v17 - 24LL); | |
v20 = *(_QWORD *)((char *)v18 + v19 + 240); | |
if ( !v20 ) | |
break; | |
if ( *(_BYTE *)(v20 + 56) ) | |
{ | |
v21 = *(_BYTE *)(v20 + 67); | |
} | |
else | |
{ | |
std::ctype<char>::_M_widen_init(*(_QWORD *)((char *)v18 + v19 + 240)); | |
v21 = (*(int (__fastcall **)(__int64, signed __int64))(*(_QWORD *)v20 + 48LL))(v20, 10LL); | |
} | |
v22 = (std::ostream *)std::ostream::put(v18, v21); | |
std::ostream::flush(v22); | |
v16 = (const char **)((char *)v16 + 4); | |
if ( v5 == v16 ) | |
goto LABEL_32; | |
} | |
std::__throw_bad_cast(); | |
LABEL_38: | |
std::__throw_bad_alloc(); | |
LABEL_39: | |
v24 = std::__throw_bad_alloc(); | |
if ( src ) | |
operator delete(src); | |
if ( v25 ) | |
operator delete(v25); | |
if ( v28 ) | |
operator delete((void *)v28); | |
_Unwind_Resume(v24, argv); | |
} | |
LABEL_32: | |
if ( v15 ) | |
operator delete(v15); | |
if ( v28 ) | |
operator delete((void *)v28); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment