-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding trampoline; prefix_preprocessor; kv headers
- Loading branch information
Showing
6 changed files
with
280 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// g++ -E add_prefix_preprocessor.cpp -o add_prefix_preprocessor -I ~/bin/boost_1_68_0 | ||
|
||
#include <boost/preprocessor/cat.hpp> | ||
#include <boost/preprocessor/seq/enum.hpp> | ||
#include <boost/preprocessor/seq/for_each.hpp> | ||
|
||
#define ADD_PREFIX(r, prefix, element) (BOOST_PP_CAT(prefix, element)) | ||
#define EXPAND(RPCS) BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_FOR_EACH(ADD_PREFIX, &NestedAsyncService::Request, RPCS)) | ||
|
||
struct NestedAsyncService { | ||
void RequestAppend() {} | ||
void RequestGetServerInfo() {} | ||
}; | ||
|
||
template <class... T> | ||
void test(T...) { | ||
|
||
} | ||
|
||
int main(void) { | ||
//auto i = ADD_PREFIX(Append); | ||
//test(EXPAND((Append))); | ||
test(EXPAND((Append)(GetServerInfo))); | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
#include <variant> | ||
#include <iostream> | ||
#include <functional> | ||
#include <tuple> | ||
#include <any> | ||
|
||
class Thunk { | ||
int acc_; | ||
int n_; | ||
std::any (*fptr_)(int, int); | ||
public: | ||
Thunk(int acc, int n, std::any (*fptr)(int, int)) | ||
: acc_(acc), n_(n), fptr_(fptr) {} | ||
std::any operator()() const { | ||
return (*fptr_)(acc_, n_); | ||
} | ||
}; | ||
|
||
auto trampoline = [](auto fn) { | ||
return [fn](auto arg1, auto arg2) { | ||
std::any result = fn(arg1, arg2); | ||
while(result.type() != typeid(int)) { | ||
result = std::any_cast<Thunk>(result)(); | ||
} | ||
return result; | ||
}; | ||
}; | ||
|
||
std::any adder(int acc, int n) { | ||
return n? std::any(Thunk(acc+n, n-1, adder)) : std::any(acc); | ||
} | ||
|
||
std::any add(int n) { | ||
return trampoline(adder)(0, n); | ||
} | ||
|
||
template <class Func> | ||
class thunk; | ||
|
||
template <class R, class... Args> | ||
class thunk<R (*)(Args...)> { | ||
public: | ||
using Variant = std::variant<R, thunk>; | ||
|
||
thunk(Variant(*fptr)(Args...), Args... args) | ||
: fptr_(fptr), | ||
args_(args...) {} | ||
|
||
Variant operator()() const { | ||
return std::apply(fptr_, std::move(args_)); | ||
} | ||
|
||
Variant trampoline(Args... args) const { | ||
Variant result = (*fptr_)(std::forward<Args>(args)...); | ||
while(result.index()) { | ||
result = std::get<1>(result)(); | ||
} | ||
return std::get<0>(result); | ||
} | ||
private: | ||
Variant(*fptr_)(Args...); | ||
std::tuple<Args...> args_; | ||
}; | ||
|
||
template <class R, class... Args> | ||
thunk(R(*)(Args...), Args...) -> thunk<R (*)(Args...)>; | ||
|
||
template <class R, class... Args> | ||
thunk(std::variant<R, thunk<R(*)(Args...)>>, Args...) -> thunk<R (*)(Args...)>; | ||
|
||
thunk<int (*)(int, int)>::Variant add2(int acc, int n) { | ||
if(n) | ||
return thunk<int (*)(int, int)>::Variant{add2, acc, n}; | ||
else | ||
return acc; | ||
} | ||
|
||
int main(void) { | ||
{ | ||
thunk<int (*)(int, int)> t{add2}; | ||
auto result = t.trampoline(0, 5); | ||
std::cout << std::get<0>(result) << "\n"; | ||
} | ||
|
||
{ | ||
std::any result = add(5); | ||
std::cout << std::any_cast<int>(result) << "\n"; | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
int main(int argc, char **argv) { | ||
int *array = new int[100]; | ||
delete [] array; | ||
return array[argc]; // BOOM | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
package com.linkedin.northguard.clients.common; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.Collections; | ||
import java.util.HashMap; | ||
import java.util.Iterator; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
|
||
/** | ||
* A container of header objects. Multiple values per key are allowed. Accessed in insertion order. | ||
*/ | ||
public class Headers { | ||
private static class KVPair { | ||
public byte[] key; | ||
public List<Header> value; | ||
|
||
public KVPair(byte[] key, List<Header> value) { | ||
this.key = key; | ||
this.value = value; | ||
} | ||
} | ||
|
||
private List<KVPair> kvArray = new ArrayList<>(); | ||
|
||
public Headers() {} | ||
|
||
/** | ||
* Append a header to the end of the list of headers for the contained key. | ||
* @param header A key-value pair. | ||
* @return this object. | ||
*/ | ||
public Headers add(Header header) { | ||
List<Header> headerList = searchKey(header.key()); | ||
if (headerList == null) { | ||
headerList = new ArrayList<>(); | ||
headerList.add(header); | ||
kvArray.add(new KVPair(header.key(), headerList)); | ||
} | ||
else { | ||
headerList.add(header); | ||
} | ||
return this; | ||
} | ||
|
||
/** | ||
* Get an iterable of headers in insertion order. Calling {@link Iterator#remove()} is modifies this Header. | ||
* @param key the key. non-null. | ||
* @return A non-null iterable. Possibly empty. | ||
*/ | ||
public Iterable<Header> get(byte[] key) { | ||
List<Header> headerList = searchKey(key); | ||
return headerList == null? Collections.EMPTY_LIST : headerList; | ||
} | ||
|
||
/** | ||
* Get the last header for the key in insertion-order | ||
* @param key the key. non-null | ||
* @return The last Header if it exists, null otherwise. | ||
*/ | ||
public Header getLast(byte[] key) { | ||
List<Header> headerList = searchKey(key); | ||
if (headerList == null || headerList.isEmpty()) { | ||
return null; | ||
} | ||
else { | ||
return headerList.get(headerList.size() - 1); | ||
} | ||
} | ||
|
||
/** | ||
* Get all the stored Headers. Calling {@link Iterator#remove()} has no effect on this object. | ||
* @return An iterable of headers. | ||
*/ | ||
public Iterable<Header> getAll() { | ||
List<Header> all = new ArrayList<>(); | ||
for (KVPair pair: kvArray) { | ||
for (Header header: pair.value) { | ||
all.add(header); | ||
} | ||
} | ||
return all; | ||
} | ||
|
||
/** | ||
* Remove all the Headers associated with the input key. | ||
* @param needle the key. non-null | ||
* @return this object. | ||
*/ | ||
public Headers remove(byte[] needle) { | ||
for (int i = 0;i < kvArray.size(); i++) { | ||
if (Arrays.equals(kvArray.get(i).key, needle)) { | ||
kvArray.remove(i); | ||
break; | ||
} | ||
} | ||
return this; | ||
} | ||
|
||
private List<Header> searchKey(byte[] needle) { | ||
for (KVPair hay: kvArray) { | ||
if (Arrays.equals(hay.key, needle)) { | ||
return hay.value; | ||
} | ||
} | ||
return null; | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
#include <variant> | ||
#include <iostream> | ||
#include <functional> | ||
#include <any> | ||
|
||
//using Result = std::variant<bool, std::function<int (int,int)>>; | ||
using Result = std::any; | ||
|
||
auto trampoline = [](auto fn) { | ||
return [fn](auto arg1, auto arg2) { | ||
Result result = fn(arg1, arg2); | ||
while(result.type() != typeid(int)) { | ||
result = std::any_cast<int (*)()>(result)(); | ||
} | ||
return result; | ||
}; | ||
}; | ||
|
||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
//var variadic = require('allong.es').variadic; | ||
//var trampoline = function(fn) { | ||
// return variadic(function(ars){ | ||
// var result = fn.apply(this, args); | ||
// while(result instanceof Function) { | ||
// result = result(); | ||
// } | ||
// return result; | ||
// }); | ||
//}; | ||
|
||
var trampoline = function(fn) { | ||
return function(arg1, arg2) { | ||
var result = fn(arg1, arg2); | ||
while(result instanceof Function) { | ||
result = result(); | ||
} | ||
return result; | ||
}; | ||
}; | ||
|
||
function add(n) { | ||
var _add = trampoline(function myself(acc, n) { | ||
return n? function() { return myself(acc+n, n-1); } : acc; | ||
}); | ||
return _add(0, n); | ||
} | ||
|
||
function add_r(acc, n) { | ||
return n? n+add_r(acc, n-1) : 0; | ||
} | ||
|
||
console.log(add(5)); |