Skip to content

Instantly share code, notes, and snippets.

@qrealka
Last active July 26, 2018 08:27
Show Gist options
  • Save qrealka/fc9963f23448decac8d0099042415c1c to your computer and use it in GitHub Desktop.
Save qrealka/fc9963f23448decac8d0099042415c1c to your computer and use it in GitHub Desktop.
one prototype
// ref_counter.h
class ref_counter {
std::atomic<size_t> references;
public:
size_t aquire();
size_t release();
};
// TODO: perhaps could be better use boost TypeErasure to make it shorter
// interface.h
class interface {
// TODO: extract concepts to separate headers
struct concept : ref_counter {
virtual ~concept() = default;
virtual std::error_code query_interface(uint32_t type_id, void* object) = 0;
};
template <class T>
struct model final : concept {
T instance;
template <class U>
model(U&& x) : instance{std::forward<U>(x)} {}
std::error_code query_interface(uint32_t type_id, void* object) override { return instance.query_interface(type_id, object); }
};
boost::intrusive_ptr<concept> impl;
public:
// TODO: need to test
template <class T>
interface(T&& x) : impl{make_intrusive<model<std::decay_t<T>>>(std::forward<T>(x))} {}
// TODO: add intrusive_ptr to public interface instead of void*
std::error_code query_interface(uint32_t type_id, void* object) { return impl->query_interface(type_id, object); }
};
// service_locator.h
class service_locator {
struct concept : ref_counter {
virtual ~concept() = default;
virtual interface get_service(uint32_t type_id) = 0;
};
template <class T>
struct model final : concept {
T instance;
template <class U>
model(U&& x) : instance{std::forward<U>(x)} {}
interface get_service(uint32_t type_id) override { return instance.get_service(type_id); }
};
boost::intrusive_ptr<concept> impl;
public:
template <class T>
service_locator(T&& x) : impl{make_intrusive<model<std::decay_t<T>>>(std::forward<T>(x))} {}
interface get_service(uint32_t type_id) { return impl->get_service(type_id);}
};
// file_handle.h
class file_hanle {
public:
using id = std::string;
private:
struct concept {
virtual ~concept() = default;
virtual const boost::path& get_local_path() const = 0;
virtual ASFileSys get_filesys() const = 0;
virtual const id& get_id() const = 0;
};
template <class T>
struct model final : concept {
T instance;
template <class U>
model(U&& x) : instance{std::forward<U>(x)} {}
const boost::path& get_local_path() const override { return instance.get_local_path(); };
ASFileSys get_filesys() const override { return instance.get_filesys(); };
const id& get_id() const override { return instance.get_id(); };
};
std::unique_ptr<concept> impl;
public:
template <class T>
file_hanle(T&& x) : impl{std::make_unique<model<std::decay_t<T>>>(std::forward<T>(x))} {}
const boost::path& get_local_path() const { return impl->get_local_path(); };
ASFileSys get_filesys() const { return impl->get_filesys(); };
const id& get_id() const { return impl->get_id(); };
};
// remote_file.h
template<class Tag> class service;
class remote_file {
service<remote_file>& backend();
const service<remote_file>& backend() const;
public:
remote_file(service_locator locator, boost::string_ref url);
const file_handle& get_handle() const;
file_permission_checker check_permissions() const;
file_accessor remote_access();
};
template<>
class service<remote_file> {
public:
virtual std::error_code download(file_handle file, progress_callback progress) = 0;
virtual std::error_code upload(file_handle file, progress_callback progress) = 0;
virtual std::error_code checkout(file_handle file, progress_callback progress) = 0;
virtual std::error_code checkin(file_handle file, progress_callback progress) = 0;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment