Skip to content

Commit

Permalink
Merge pull request #1 from sreiter/vg_ip_2
Browse files Browse the repository at this point in the history
Vg ip 2: Use C++20, build shared library, improve performance and usability.
  • Loading branch information
sreiter authored Jul 21, 2024
2 parents a281d01 + 758416e commit 4868790
Show file tree
Hide file tree
Showing 37 changed files with 1,083 additions and 202 deletions.
26 changes: 21 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,19 @@ option (MOOSE_BUILD_TESTS "Build the moose tests")

project (libmoose)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

set (mooseSrc src/moose/archive.cpp
src/moose/binary_reader.cpp
src/moose/input_archive.cpp
src/moose/json_archive_in.cpp
src/moose/json_archive_out.cpp
src/moose/json_reader.cpp
src/moose/json_writer.cpp
src/moose/output_archive.cpp
src/moose/type.cpp
src/moose/types.cpp
src/moose/version.cpp)

add_library(moose STATIC ${mooseSrc})
add_library(moose SHARED ${mooseSrc})

target_include_directories(moose
PUBLIC
Expand All @@ -50,14 +53,27 @@ target_include_directories(moose
${CMAKE_CURRENT_SOURCE_DIR}/deps/rapidjson-v1.1.0.s1/include
)

target_compile_features(moose PUBLIC cxx_std_17)
target_compile_features(moose PUBLIC cxx_std_20)

if(MSVC)
target_compile_options(moose PRIVATE /W4 /WX)
#/wd5054 is a warning from rapidjson.
target_compile_options(moose PRIVATE /W4 /WX /wd5054)
else()
target_compile_options(moose PRIVATE -Wall -Wextra -Wpedantic -Werror)
endif()

target_compile_definitions (moose PRIVATE MOOSE_COMPILING_LIBRARY)

include (FetchContent)
FetchContent_Declare (
magic_enum
GIT_REPOSITORY https://github.com/Neargye/magic_enum
GIT_TAG v0.9.6
GIT_SHALLOW ON)
FetchContent_MakeAvailable (magic_enum)

target_link_libraries (moose PUBLIC magic_enum)

if (MOOSE_BUILD_SAMPLE)
add_subdirectory (sample)
endif ()
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# moose      [![Build Status](https://travis-ci.com/sreiter/moose.svg?branch=master)](https://travis-ci.com/sreiter/moose)
# moose
## Introduction
**Moose** (**MO**ose **O**bject **SE**rialization) is a *BSD* licensed *C++* library for the serialization of complex data structures.

Expand All @@ -18,7 +18,7 @@ function for a given ```Object``` type, or by providing a method

one can add serialization support for custom types.

The implementation of **moose** is kept simple on purpose to allow users of the library to easily create **custom archives**, which may be used to support more file formats.
The implementation of **moose** is kept simple on purpose to allow users of the library to easily create **custom readers/writers**, which may be used to support more file formats.

Another interesting application for **archives** is the generation and synchronization of **GUI** elements given a serializable object.

Expand Down Expand Up @@ -52,7 +52,7 @@ Please note that ```ClassA``` and ```ClassB``` derive from a common base class `

In addition to the **moose** library, the following executable will be build:

sample/moosesample
sample/moose_sample

## Building moose as a part of your project
To build **moose** as part of your project, simply add the line
Expand Down
15 changes: 8 additions & 7 deletions include/moose/archive.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

#include <memory>
#include <string>
#include <moose/export.h>
#include <moose/range.h>
#include <moose/type_traits.h>
#include <moose/version.h>
Expand All @@ -42,16 +43,16 @@ namespace moose
class Archive
{
public:
Archive (std::shared_ptr<Reader> archive);
Archive (std::shared_ptr<Writer> archive);
MOOSE_EXPORT Archive (std::shared_ptr<Reader> archive);
MOOSE_EXPORT Archive (std::shared_ptr<Writer> archive);

/** For output archives, latestVersion is stored as version of the currently processed type
and is also returned.
For input archives, the type version stored in the underlying archive is returned.
If no version was stored, {0,0,0} is returned.
*/
auto type_version (Version const& latestVersion) -> Version;
MOOSE_EXPORT auto type_version (Version const& latestVersion) -> Version;

/** \brief Read/write without default value.
If the archive is reading and the given name can not be found, an exception is thrown.
Expand All @@ -74,12 +75,12 @@ namespace moose
template <class T>
void operator () (const char* name, T const& value, const T& defVal, Hint hint = Hint::None);

bool is_reading () const;
bool is_writing () const;
MOOSE_EXPORT bool is_reading () const;
MOOSE_EXPORT bool is_writing () const;

private:
bool begin_entry (const char* name, ContentType contentType, Hint hint);
void end_entry (const char* name, ContentType contentType);
MOOSE_EXPORT bool begin_entry (const char* name, ContentType contentType, Hint hint);
MOOSE_EXPORT void end_entry (const char* name, ContentType contentType);

/// Used to allow for different overloads based on the entryType.
template <EntryType entryType>
Expand Down
58 changes: 47 additions & 11 deletions include/moose/archive.i
Original file line number Diff line number Diff line change
Expand Up @@ -132,16 +132,16 @@ namespace moose
{
if (is_writing ())
{
auto const& type = Types::get_polymorphic (instance);
auto const& type = types ().get_polymorphic (instance);
mOutput->write_type_name (type.name ());
return type;
}
else
{
auto const& typeName = mInput->type_name ();
if (typeName.empty ())
return Types::get <T> ();
return Types::get (typeName);
return types ().get <T> ();
return types ().get (typeName);
}
}

Expand Down Expand Up @@ -205,21 +205,57 @@ namespace moose
template <class T>
void Archive::archive (const char* name, T& value, EntryTypeDummy <EntryType::Vector>)
{
using Traits = TypeTraits<T>;
using ValueType = typename Traits::ValueType;

constexpr bool unpack = wantsToUnpack<T> () && canBeUnpacked<ValueType> ();

if (is_reading ())
{
TypeTraits<T>::clear (value);
while(mInput->array_has_next (name))
Traits::clear (value);
if constexpr (unpack)
{
while(mInput->array_has_next (name))
{
ValueType childValue;
auto childRange = TypeTraits<ValueType>::toRange (childValue);
for (auto i = childRange.begin; i != childRange.end; ++i)
{
if (!mInput->array_has_next (name))
throw ArchiveError () << "Too few entries while reading range '" << name << "'";

(*this) ("", *i);
}
Traits::pushBack (value, childValue);
}
}
else
{
using ValueType = typename TypeTraits<T>::ValueType;
ValueType tmpVal = detail::GetInitialValue <ValueType> ();
(*this) ("", tmpVal);
TypeTraits<T>::pushBack (value, tmpVal);
while(mInput->array_has_next (name))
{
ValueType tmpVal = detail::GetInitialValue <ValueType> ();
(*this) ("", tmpVal);
Traits::pushBack (value, tmpVal);
}
}
}
else
{
// Writing a vector type is the same as writing a range
archive (name, value, EntryTypeDummy <EntryType::Range> ());
if constexpr (unpack)
{
auto range = Traits::toRange (value);
for (auto i = range.begin; i != range.end; ++i)
{
auto childRange = TypeTraits<ValueType>::toRange (*i);
for (auto j = childRange.begin; j != childRange.end; ++j)
(*this) ("", *j);
}
}
else
{
// Writing a vector type is the same as writing a range
archive (name, value, EntryTypeDummy <EntryType::Range> ());
}
}
}

Expand Down
81 changes: 81 additions & 0 deletions include/moose/binary_reader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// This file is part of moose, a C++ serialization library
//
// Copyright (C) 2024 Volume Graphics
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma once

#include <moose/export.h>
#include <moose/reader.h>

#include <memory>
#include <stack>

namespace moose
{
class BinaryReader : public Reader {
public:
MOOSE_EXPORT static auto fromFile (const char* filename) -> std::shared_ptr<BinaryReader>;

public:
BinaryReader () = delete;
MOOSE_EXPORT BinaryReader (BinaryReader&& other) = default;
MOOSE_EXPORT BinaryReader (std::istream& in);
MOOSE_EXPORT BinaryReader (std::shared_ptr<std::istream> in);

BinaryReader (BinaryReader const&) = delete;

MOOSE_EXPORT ~BinaryReader () override = default;

BinaryReader& operator = (BinaryReader const&) = delete;
MOOSE_EXPORT BinaryReader& operator = (BinaryReader&& other) = default;

bool begin_entry (const char* name, ContentType type) override;
void end_entry (const char* name, ContentType type) override;

bool array_has_next (const char* name) const override;

auto type_name () const -> std::string override;
auto type_version () const -> Version override;

void read (const char* name, bool& value) const override;
void read (const char* name, double& value) const override;
void read (const char* name, std::string& value) const override;

private:
struct Entry
{
ContentType mType;
bool mArrayHasNext {false};
};

private:
auto current () -> Entry&;
auto current () const -> Entry const&;
bool readArrayHasNext ();
auto in () const -> std::istream&;

private:
std::shared_ptr<std::istream> mStreamStorage;
std::istream* mIn;
std::stack<Entry> mEntries;
};
}// end of namespace moose
78 changes: 78 additions & 0 deletions include/moose/binary_writer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// This file is part of moose, a C++ serialization library
//
// Copyright (C) 2024 Volume Graphics
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#pragma once

#include <fstream>
#include <stack>
#include <memory>
#include <moose/writer.h>

namespace moose
{

/** Writes binary data to a given stream, using its
`write (const char_type* s, std::streamsize count)` method.
*/
template <class STREAM = std::ofstream>
class BinaryWriter : public Writer
{
public:
static auto toFile (const char* filename) -> std::shared_ptr<BinaryWriter>;

BinaryWriter (STREAM& out);
BinaryWriter (std::shared_ptr<STREAM> out);

BinaryWriter (BinaryWriter const&) = delete;
BinaryWriter (BinaryWriter&& other) = default;


~BinaryWriter () override = default;

BinaryWriter& operator = (BinaryWriter const&) = delete;
BinaryWriter& operator = (BinaryWriter&& other) = default;

bool begin_entry (const char* name, ContentType type, Hint hint) override;
void end_entry (const char* name, ContentType type) override;

void write_type_name (std::string const& typeName) override;
void write_type_version (Version const& version) override;

void write (const char* name, bool value) override;
void write (const char* name, double value) override;
void write (const char* name, std::string const& value) override;

private:
auto out () -> STREAM&;

private:
std::shared_ptr<STREAM> mStreamStorage;
STREAM* mOut;
std::stack<ContentType> mContentStack;
std::stack<std::string> mNameStack;
};

}// end of namespace moose

#include <moose/binary_writer.i>
Loading

0 comments on commit 4868790

Please sign in to comment.