diff --git a/.clang-format b/.clang-format index 6205f67..710226b 100644 --- a/.clang-format +++ b/.clang-format @@ -112,9 +112,6 @@ SpacesInCStyleCastParentheses: false SpacesInParentheses: false SpacesInSquareBrackets: false Standard: Cpp11 -StatementMacros: - - Q_UNUSED - - QT_REQUIRE_VERSION TabWidth: 4 UseTab: ForContinuationAndIndentation ... diff --git a/SConstruct b/SConstruct index 706e9dc..f38a274 100644 --- a/SConstruct +++ b/SConstruct @@ -29,8 +29,8 @@ def add_kel_source_files(self, sources, filetype, lib_env=None, shared=False, ta sources.append( self.StaticObject( target=target_name, source=path ) ) pass -env=Environment(CPPPATH=['#source/kelgin','#source','#','#driver'], - CXX='clang++', +env=Environment(ENV=os.environ, CPPPATH=['#source/kelgin','#source','#','#driver'], + CXX='g++', CPPDEFINES=['GIN_UNIX'], CXXFLAGS=['-std=c++17','-g','-Wall','-Wextra'], LIBS=['gnutls']) diff --git a/source/kelgin/async.h b/source/kelgin/async.h index af69cfc..2e2cf47 100644 --- a/source/kelgin/async.h +++ b/source/kelgin/async.h @@ -183,7 +183,7 @@ public: * Useful for resource lifetime control. */ template - [[nodiscard]] Conveyor attach(Args &&...args); + [[nodiscard]] Conveyor attach(Args &&... args); /** @todo implement * This method limits the total amount of passed elements @@ -601,7 +601,7 @@ private: std::tuple attached_data; public: - AttachConveyorNode(Own &&dep, Args &&...args) + AttachConveyorNode(Own &&dep, Args &&... args) : AttachConveyorNodeBase(std::move(dep)), attached_data{ std::move(args...)} {} }; diff --git a/source/kelgin/async.tmpl.h b/source/kelgin/async.tmpl.h index 67312e5..292a38d 100644 --- a/source/kelgin/async.tmpl.h +++ b/source/kelgin/async.tmpl.h @@ -73,7 +73,7 @@ template Conveyor Conveyor::buffer(size_t size) { template template -Conveyor Conveyor::attach(Args &&...args) { +Conveyor Conveyor::attach(Args &&... args) { Own> attach_node = heap>(std::move(node), std::move(args...)); return Conveyor{std::move(attach_node), storage}; diff --git a/source/kelgin/common.h b/source/kelgin/common.h index 3939076..58d4d2b 100644 --- a/source/kelgin/common.h +++ b/source/kelgin/common.h @@ -39,11 +39,11 @@ template using Our = std::shared_ptr; template using Lent = std::weak_ptr; -template Own heap(Args &&...args) { +template Own heap(Args &&... args) { return Own(new T(std::forward(args)...)); } -template Our share(Args &&...args) { +template Our share(Args &&... args) { return std::make_shared(std::forward(args)...); } diff --git a/source/kelgin/json.h b/source/kelgin/json.h index 189a491..edb5b6f 100644 --- a/source/kelgin/json.h +++ b/source/kelgin/json.h @@ -835,9 +835,7 @@ Error JsonCodec::decodeValue(Own &message, Buffer &buffer, decodeNull(buffer); message = std::move(msg_null); } break; - default: { - return criticalError("Cannot identify next JSON value"); - } + default: { return criticalError("Cannot identify next JSON value"); } } skipWhitespace(buffer); diff --git a/source/kelgin/message.h b/source/kelgin/message.h index 9ddb58e..65330e1 100644 --- a/source/kelgin/message.h +++ b/source/kelgin/message.h @@ -4,122 +4,47 @@ #include #include #include +#include #include "common.h" +#include "schema.h" #include "string_literal.h" namespace gin { -class Message { +class MessageBase { protected: bool set_explicitly = false; public: - template T &as() { - static_assert(std::is_base_of()); - return reinterpret_cast(*this); + template T &as() { + static_assert(std::is_base_of()); + return dynamic_cast(*this); } - template const T &as() const { - static_assert(std::is_base_of()); - return reinterpret_cast(*this); + template const T &as() const { + static_assert(std::is_base_of()); + return dynamic_cast(*this); } }; /* - * Representing all primitive types + * Representing all message types + * Description which type to use happens through the use of the schema classes in schema.h + * The message classes are a container class which either contains singular types or has + * some form of encoding in a buffer present */ -template class MessagePrimitive : public Message { + +template +class Message...>, Container> final + : public MessageBase { private: - T value; + using SchemaType = schema::Struct...>; + using MessageType = + Message; + Container container; - friend class Builder; - friend class Reader; + static_assert(std::is_same_v, "Container should have same Schema as Message"); -public: - MessagePrimitive() = default; - - class Reader; - class Builder { - private: - MessagePrimitive &message; - - public: - Builder(MessagePrimitive &message) : message{message} {} - - constexpr void set(const T &value) { - message.value = value; - message.set_explicitly = true; - } - - Reader asReader() { return Reader{message}; } - }; - - class Reader { - private: - MessagePrimitive &message; - - public: - Reader(MessagePrimitive &message) : message{message} {} - - const T &get() const { return message.value; } - - bool isSetExplicitly() const { return message.set_explicitly; } - - Builder asBuilder() { return Builder{message}; } - }; -}; - -template <> class MessagePrimitive : public Message { -private: - std::string value; - - friend class Builder; - friend class Reader; - -public: - MessagePrimitive() = default; - - class Reader; - class Builder { - private: - MessagePrimitive &message; - - public: - Builder(MessagePrimitive &message) : message{message} {} - - void set(std::string_view value) { - message.value = std::string{value}; - message.set_explicitly = true; - } - /* - void set(std::string &&value) { - message.value = std::move(value); - message.set_explicitly = true; - } - */ - - Reader asReader() { return Reader{message}; } - }; - - class Reader { - private: - MessagePrimitive &message; - - public: - Reader(MessagePrimitive &message) : message{message} {} - - std::string_view get() const { return std::string_view{message.value}; } - - bool isSetExplicitly() const { return message.set_explicitly; } - - Builder asBuilder() { return Builder{message}; } - }; -}; - -template class MessageList : public Message { -private: - using tuple_type = std::tuple; - tuple_type elements; friend class Builder; friend class Reader; @@ -127,312 +52,53 @@ public: class Reader; class Builder { private: - MessageList &message; + MessageType &message; public: - Builder(MessageList &message) : message{message} { - message.set_explicitly = true; + Builder(MessageType &msg) : message{msg} {} + + Reader asReader() { return Reader{MessageType & message}; } + + template + typename Container::Element::Builder init(){ + return typename Container::Element::Builder{message.container.get()}; } - template - constexpr typename std::tuple_element_t::Builder init() { - std::tuple_element_t &msg_ref = - std::get(message.elements); - return - typename std::tuple_element_t::Builder{msg_ref}; - } + template typename Container::Element::Builder init(){ + constexpr size_t i = MessageParameterPackIndex::Value; - Reader asReader() { return Reader{message}; } + return init(); + } }; class Reader { private: - MessageList &message; + MessageType &message; public: - Reader(MessageList &message) : message{message} {} + Reader(MessageType &msg) : message{msg} {} - template - constexpr typename std::tuple_element_t::Reader get() { - return std::get(message.elements); + Builder asBuilder() { return Builder{MessageType & message}; } + + template + typename Container::Element::Reader get(){ + return typename Container::Element::Reader{message.container.get()}; } - size_t size() const { return std::tuple_size::value; } + template typename Container::Element::Reader get(){ + constexpr size_t i = MessageParameterPackIndex::Value; - bool isSetExplicitly() const { return message.set_explicitly; } - - Builder asBuilder() { return Builder{message}; } + return get(); + } }; }; -/// @todo how to do initialization? -template class MessageArray : public Message { +template +class Message, Container> final : public MessageBase { private: - using array_type = std::vector; - array_type elements; - friend class Builder; - friend class Reader; - + Container container; public: - class Reader; - class Builder { - private: - MessageArray &message; - public: - Builder(MessageArray &message) : message{message} { - message.set_explicitly = true; - } - - constexpr typename T::Builder init(size_t i) { - T &msg_ref = message.elements.at(i); - return typename T::Builder{msg_ref}; - } - - Reader asReader() { return Reader{message}; } - }; - - class Reader { - private: - MessageArray &message; - - public: - Reader(MessageArray &message) : message{message} {} - - constexpr typename T::Reader get(size_t i) { - return message.elements.at(i); - } - - size_t size() const { return message.elements.size(); } - - bool isSetExplicitly() const { return message.set_explicitly; } - - Builder asBuilder() { return Builder{message}; } - }; -}; - -template struct MessageStructMember; - -template -struct MessageStructMember> { - T value; -}; - -/* - * Helper structs which retrieve - * the index of a parameter pack based on the index - * or - * a type based on the index - * Pass N as the index for the desired type - * or - * a type to get the first occurence of a type index - */ -template struct ParameterPackType; - -template struct ParameterPackType<0, T, TL...> { - using type = T; -}; - -template -struct ParameterPackType { - using type = typename ParameterPackType::type; -}; - -template struct ParameterPackIndex; - -template struct ParameterPackIndex { - static constexpr size_t value = 0u; -}; - -template -struct ParameterPackIndex { - static constexpr size_t value = 1u + ParameterPackIndex::value; -}; - -template class MessageStruct; - -/* - * Since no value is retrieved from the keys, I only need a value tuple - */ -template -class MessageStruct...> : public Message { -private: - using value_type = std::tuple; - value_type values; - friend class Builder; - friend class Reader; - -public: - class Reader; - class Builder { - private: - MessageStruct...> &message; - - public: - Builder(MessageStruct...> &message) - : message{message} { - message.set_explicitly = true; - } - - template - constexpr typename std::tuple_element_t::Builder init() { - std::tuple_element_t &msg_ref = - std::get(message.values); - return - typename std::tuple_element_t::Builder{msg_ref}; - } - - template - constexpr - typename std::tuple_element_t::value, - value_type>::Builder - init() { - std::tuple_element_t::value, value_type> - &msg_ref = std::get::value>( - message.values); - return typename std::tuple_element_t< - ParameterPackIndex::value, value_type>::Builder{ - msg_ref}; - } - - Reader asReader() { return Reader{message}; } - }; - class Reader { - private: - MessageStruct...> &message; - - public: - Reader(MessageStruct...> &message) - : message{message} {} - - template - constexpr typename std::tuple_element_t::Reader get() { - std::tuple_element_t &msg_ref = - std::get(message.values); - return - typename std::tuple_element_t::Reader{msg_ref}; - } - - template - constexpr - typename std::tuple_element_t::value, - value_type>::Reader - get() { - std::tuple_element_t::value, value_type> - &msg_ref = std::get::value>( - message.values); - return typename std::tuple_element_t< - ParameterPackIndex::value, value_type>::Reader{ - msg_ref}; - } - - constexpr size_t size() { return std::tuple_size::value; } - - bool isSetExplicitly() const { return message.set_explicitly; } - - Builder asBuilder() { return Builder{message}; } - }; -}; - -template struct MessageUnionMember; - -template -struct MessageUnionMember> { - T value; -}; - -template class MessageUnion; - -/// @todo copied from MessageStruct, but the acces is different, since -/// only one value can be set at the same time. -template -class MessageUnion...> : public Message { -private: - using value_type = std::variant...>; - value_type values; - friend class Builder; - friend class Reader; - -public: - class Reader; - class Builder { - private: - MessageUnion...> &message; - - public: - Builder(MessageUnion...> &message) - : message{message} { - message.set_explicitly = true; - } - - template - constexpr typename ParameterPackType::type::Builder init() { - message.values = - typename std::variant_alternative_t{}; - typename ParameterPackType::type &msg_ref = - std::get(message.values).value; - return typename ParameterPackType::type::Builder{msg_ref}; - } - - template - constexpr typename ParameterPackType::value, - V...>::type::Builder - init() { - message.values = typename std::variant_alternative_t< - ParameterPackIndex::value, value_type>{}; - typename ParameterPackType::value, - V...>::type &msg_ref = - std::get::value>(message.values) - .value; - return - typename ParameterPackType::value, - V...>::type::Builder{msg_ref}; - } - - Reader asReader() { return Reader{message}; } - }; - class Reader { - private: - MessageUnion...> &message; - - public: - Reader(MessageUnion...> &message) - : message{message} {} - - template - constexpr typename ParameterPackType::type::Reader get() { - typename ParameterPackType::type &msg_ref = - std::get(message.values).value; - return typename ParameterPackType::type::Reader{msg_ref}; - } - - template - constexpr typename ParameterPackType::value, - V...>::type::Reader - get() { - typename ParameterPackType::value, - V...>::type &msg_ref = - std::get::value>(message.values) - .value; - return - typename ParameterPackType::value, - V...>::type::Reader{msg_ref}; - } - - template constexpr bool holdsAlternative() { - return std::holds_alternative::value, value_type>>( - message.values); - } - - size_t index() const { return message.values.index(); } - - bool isSetExplicitly() const { return message.set_explicitly; } - - constexpr size_t size() { return std::variant_size::value; } - - Builder asBuilder() { return Builder{message}; } - }; }; class MessageReader { @@ -454,5 +120,5 @@ public: } }; -inline MessageBuilder heapMessageBuilder() { return MessageBuilder{}; } +inline MessageBuilder messageBuilder() { return MessageBuilder{}; } } // namespace gin diff --git a/source/kelgin/message_container.h b/source/kelgin/message_container.h new file mode 100644 index 0000000..f6a2b73 --- /dev/null +++ b/source/kelgin/message_container.h @@ -0,0 +1,46 @@ +#pragma once + +#include "schema.h" + +namespace gin { +template +class MessageContainer; + +template class Message; + +template struct MessageParameterPackType ; + +template struct MessageParameterPackType <0, TN, T...> { + using Type = T; +}; + +template struct MessageParameterPackType { + using Type = typename MessageParameterPackType::Type; +}; + +template struct MessageParameterPackIndex; + +template struct MessageParameterPackIndex { + static constexpr size_t Value = 0u; +}; + +template struct MessageParameterPackIndex { + static constexpr size_t Value = 1u + MessageParameterPackIndex::Value; +}; + +template class MessageContainer...>> { +private: + using ValueType = std::tuple>...>; + ValueType values; +public: + using SchemaType = schema::Struct...>; + + template + using Element = MessageParameterPackType>...>; + + template + Element& get(){ + return std::get(values); + } +}; +} diff --git a/source/kelgin/schema.h b/source/kelgin/schema.h index 1b86baf..897b3b7 100644 --- a/source/kelgin/schema.h +++ b/source/kelgin/schema.h @@ -1,14 +1,11 @@ #pragma once -#include +#include "string_literal.h" namespace gin { namespace schema { -template struct NamedMember; - -template -struct NamedMember> {}; +template struct NamedMember {}; template struct Struct {}; @@ -21,5 +18,38 @@ template struct Union...> {}; template struct Array {}; struct String {}; + +struct SignedIntegral {}; +struct UnsignedIntegral {}; +struct FloatingPoint {}; + +template +struct Primitive { + static_assert( + ( + (std::is_same_v || std::is_same_v) && + (N == 1 || N == 2 || N == 4 || N == 8) + )|| + ( + std::is_same_v && + (N==4 || N == 8) + ), + "Primitive Type is not supported" + ); +}; + +using Int8 = Primitive; +using Int16 = Primitive; +using Int32 = Primitive; +using Int64 = Primitive; + +using UInt8 = Primitive; +using UInt16 = Primitive; +using UInt32 = Primitive; +using UInt64 = Primitive; + +using Float32 = Primitive; +using Float64 = Primitive; + } // namespace schema } // namespace gin diff --git a/source/kelgin/string_literal.h b/source/kelgin/string_literal.h index b19cb54..e017ca6 100644 --- a/source/kelgin/string_literal.h +++ b/source/kelgin/string_literal.h @@ -9,17 +9,23 @@ namespace gin { * literal. It guarantees compile time uniqueness and thus allows using strings * in template parameters. */ -template class StringLiteral { +template