Poc example works.

This commit is contained in:
Kruno Tomola Fabro 2016-08-26 12:21:42 +01:00
parent 16a42298c5
commit 9469d09c57
9 changed files with 256 additions and 0 deletions

View File

View File

View File

@ -11,3 +11,8 @@ add_executable(profile profile.cpp)
target_link_libraries(profile memgraph)
target_link_libraries(profile Threads::Threads)
target_link_libraries(profile ${fmt_static_lib})
include_directories(${CMAKE_SOURCE_DIR}/poc)
add_executable(isolation isolation.cpp isolation/header.cpp)
target_link_libraries(isolation ${fmt_static_lib})

24
poc/isolation.cpp Normal file
View File

@ -0,0 +1,24 @@
// Making it as first import will prevent accidentaly importing to isolated
// other code.
#include "isolation/isolated.hpp"
#include <iostream>
#include "isolation/db.hpp"
#include "isolation/header.hpp"
using namespace base;
int main()
{
std::cout << sizeof(Accessor) << " : " << alignof(Accessor) << "\n";
Db db;
db.data = 207;
auto ret = sha::do_something(reinterpret_cast<sha::Db &>(db));
std::cout << ret << std::endl;
return 0;
}

28
poc/isolation/db.hpp Normal file
View File

@ -0,0 +1,28 @@
#include <string>
namespace base
{
class Accessor
{
public:
char before = ~((char)-1);
int data = 0;
size_t after = ~((size_t)-1);
};
class Name
{
public:
Name(const char *str) : name(std::string(str)) {}
std::string name;
};
class Db
{
public:
int accessed = 0;
int data = 0;
Name name = {"name"};
};
}

59
poc/isolation/header.cpp Normal file
View File

@ -0,0 +1,59 @@
#include "isolation/header.hpp"
#include "isolation/db.hpp"
template <class TO, class FROM>
TO &ref_as(FROM &ref)
{
return (*reinterpret_cast<TO *>(&ref));
}
template <class TO, class FROM>
TO value_as(FROM &&ref)
{
return std::move((*reinterpret_cast<TO *>(&ref)));
}
sha::Accessor::Accessor(const sha::Accessor::Accessor &other)
: Sized(sizeof(base::Accessor), alignof(base::Accessor))
{
as<base::Accessor>() = other.as<base::Accessor>();
}
sha::Accessor::Accessor(sha::Accessor::Accessor &&other)
: Sized(sizeof(base::Accessor), alignof(base::Accessor))
{
as<base::Accessor>() = value_as<base::Accessor>(other);
}
sha::Accessor &sha::Accessor::operator=(const sha::Accessor::Accessor &other)
{
// TODO
return *this;
}
sha::Accessor &sha::Accessor::operator=(sha::Accessor::Accessor &&other)
{
// TODO
return *this;
}
int sha::Accessor::get_prop(sha::Name &name)
{
return as<base::Accessor>().data;
}
sha::Accessor sha::Db::access()
{
auto &db = as<base::Db>();
db.accessed++;
base::Accessor acc;
acc.data = db.data;
return sha::Accessor(value_as<sha::Accessor>(acc));
}
sha::Name &sha::Db::get_name(const char *str)
{
auto &db = as<base::Db>();
db.accessed++;
return ref_as<sha::Name>(db.name);
}

123
poc/isolation/header.hpp Normal file
View File

@ -0,0 +1,123 @@
#pragma once
// All fake types should be defined here as a interface.
#include <cassert>
#include <type_traits>
namespace sha
{
// Sized
class Name;
class Db;
// Unsized
class Accessor;
// Marks types which will be passed only be ref/pointer.
class Unsized
{
public:
// This will assure that this class/derived classes can't be instantiated,
// copyed or moved.
// This way the other side can't "accidentaly" create/copy/move or destroy
// this type because that would be errornus.
Unsized() = delete;
Unsized(const Unsized &other) = delete;
Unsized(Unsized &&other) = delete;
~Unsized() = delete;
Unsized &operator=(const Unsized &other) = delete;
Unsized &operator=(Unsized &&other) = delete;
protected:
template <class T>
T &as()
{
return (*reinterpret_cast<T *>(this));
}
template <class T>
const T &as() const
{
return (*reinterpret_cast<const T *>(this));
}
};
// Every type which will be passed by value must extends this class.
template <std::size_t size_B, std::size_t alignment_B>
class Sized
{
public:
// This will assure that this/derived class can't be instantiated.
// This way if other side can't "accidentaly" create this/derived type
// because that would be errornus.
Sized() = delete;
// This constructr also serves as a check for correctness of size and
// aligment.
Sized(std::size_t _size_B, std::size_t _alignment_B)
{
assert(size_B == _size_B);
assert(alignment_B == _alignment_B);
}
protected:
template <class T>
T &as()
{
return (*reinterpret_cast<T *>(&data));
}
template <class T>
const T &as() const
{
return (*reinterpret_cast<const T *>(&data));
}
private:
// Here the first argument for template is size of struct in bytes. While
// the second one is aligment of struct in bytes. Every class which will be
// passed by value must have this kind of aligned storage with correct size
// and aligment for that type. Unit tests to check this must be present.
// Example would be:
// std::aligned_storage<sizeof(std::set<int>), alignof(std::set<int>)>
// While the resoults of sizeof and alignof would be passed as template
// argumetns.
// This values would be checked in tests like the following for example
// above:
// assert(sizeof(Accessor)==sizeof(std::set<int>));
// assert(alignof(Accessor)==alignof(std::set<int>));
std::aligned_storage<size_B, alignment_B> data;
};
// Type which will be passed by value so it's real size matters.
class Accessor : private Sized<16, 8>
{
public:
// If the underlying type can't be copyed or moved this two constructors
// would be deleted.
Accessor(const Accessor &other);
Accessor(Accessor &&other);
// If the underlying type can't be copyed or moved this two operators
// would be deleted.
Accessor &operator=(const Accessor &other);
Accessor &operator=(Accessor &&other);
int get_prop(Name &name);
};
// Type which will be passed by ref/pointer only so it's size doesnt matter.
class Name : private Unsized
{
};
// Type which will be passed by ref/pointer only so it's size doesnt matter.
class Db : public Unsized
{
public:
Accessor access();
Name &get_name(const char *str);
};
}

View File

@ -0,0 +1,17 @@
// This is the file of isolated code. It has access only to header.hpp
#include "isolation/header.hpp"
namespace sha
{
int do_something(Db &db)
{
auto &name = db.get_name("name");
auto acc = db.access();
auto ret = acc.get_prop(name);
return ret;
}
}

0
src/barrier/barrier.cpp Normal file
View File