Poc example works.
This commit is contained in:
parent
16a42298c5
commit
9469d09c57
0
include/barrier/barrier.hpp
Normal file
0
include/barrier/barrier.hpp
Normal file
0
include/barrier/common.hpp
Normal file
0
include/barrier/common.hpp
Normal 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
24
poc/isolation.cpp
Normal 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
28
poc/isolation/db.hpp
Normal 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
59
poc/isolation/header.cpp
Normal 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
123
poc/isolation/header.hpp
Normal 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);
|
||||
};
|
||||
}
|
17
poc/isolation/isolated.hpp
Normal file
17
poc/isolation/isolated.hpp
Normal 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
0
src/barrier/barrier.cpp
Normal file
Loading…
Reference in New Issue
Block a user