Skip to content

Commit 4868790

Browse files
authored
Merge pull request #1 from sreiter/vg_ip_2
Vg ip 2: Use C++20, build shared library, improve performance and usability.
2 parents a281d01 + 758416e commit 4868790

37 files changed

+1083
-202
lines changed

CMakeLists.txt

+21-5
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,19 @@ option (MOOSE_BUILD_TESTS "Build the moose tests")
3030

3131
project (libmoose)
3232

33+
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
34+
3335
set (mooseSrc src/moose/archive.cpp
36+
src/moose/binary_reader.cpp
3437
src/moose/input_archive.cpp
35-
src/moose/json_archive_in.cpp
36-
src/moose/json_archive_out.cpp
38+
src/moose/json_reader.cpp
39+
src/moose/json_writer.cpp
3740
src/moose/output_archive.cpp
3841
src/moose/type.cpp
3942
src/moose/types.cpp
4043
src/moose/version.cpp)
4144

42-
add_library(moose STATIC ${mooseSrc})
45+
add_library(moose SHARED ${mooseSrc})
4346

4447
target_include_directories(moose
4548
PUBLIC
@@ -50,14 +53,27 @@ target_include_directories(moose
5053
${CMAKE_CURRENT_SOURCE_DIR}/deps/rapidjson-v1.1.0.s1/include
5154
)
5255

53-
target_compile_features(moose PUBLIC cxx_std_17)
56+
target_compile_features(moose PUBLIC cxx_std_20)
5457

5558
if(MSVC)
56-
target_compile_options(moose PRIVATE /W4 /WX)
59+
#/wd5054 is a warning from rapidjson.
60+
target_compile_options(moose PRIVATE /W4 /WX /wd5054)
5761
else()
5862
target_compile_options(moose PRIVATE -Wall -Wextra -Wpedantic -Werror)
5963
endif()
6064

65+
target_compile_definitions (moose PRIVATE MOOSE_COMPILING_LIBRARY)
66+
67+
include (FetchContent)
68+
FetchContent_Declare (
69+
magic_enum
70+
GIT_REPOSITORY https://github.com/Neargye/magic_enum
71+
GIT_TAG v0.9.6
72+
GIT_SHALLOW ON)
73+
FetchContent_MakeAvailable (magic_enum)
74+
75+
target_link_libraries (moose PUBLIC magic_enum)
76+
6177
if (MOOSE_BUILD_SAMPLE)
6278
add_subdirectory (sample)
6379
endif ()

README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# moose      [![Build Status](https://travis-ci.com/sreiter/moose.svg?branch=master)](https://travis-ci.com/sreiter/moose)
1+
# moose
22
## Introduction
33
**Moose** (**MO**ose **O**bject **SE**rialization) is a *BSD* licensed *C++* library for the serialization of complex data structures.
44

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

1919
one can add serialization support for custom types.
2020

21-
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.
21+
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.
2222

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

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

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

55-
sample/moosesample
55+
sample/moose_sample
5656

5757
## Building moose as a part of your project
5858
To build **moose** as part of your project, simply add the line

include/moose/archive.h

+8-7
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
#include <memory>
2929
#include <string>
30+
#include <moose/export.h>
3031
#include <moose/range.h>
3132
#include <moose/type_traits.h>
3233
#include <moose/version.h>
@@ -42,16 +43,16 @@ namespace moose
4243
class Archive
4344
{
4445
public:
45-
Archive (std::shared_ptr<Reader> archive);
46-
Archive (std::shared_ptr<Writer> archive);
46+
MOOSE_EXPORT Archive (std::shared_ptr<Reader> archive);
47+
MOOSE_EXPORT Archive (std::shared_ptr<Writer> archive);
4748

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

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

77-
bool is_reading () const;
78-
bool is_writing () const;
78+
MOOSE_EXPORT bool is_reading () const;
79+
MOOSE_EXPORT bool is_writing () const;
7980

8081
private:
81-
bool begin_entry (const char* name, ContentType contentType, Hint hint);
82-
void end_entry (const char* name, ContentType contentType);
82+
MOOSE_EXPORT bool begin_entry (const char* name, ContentType contentType, Hint hint);
83+
MOOSE_EXPORT void end_entry (const char* name, ContentType contentType);
8384

8485
/// Used to allow for different overloads based on the entryType.
8586
template <EntryType entryType>

include/moose/archive.i

+47-11
Original file line numberDiff line numberDiff line change
@@ -132,16 +132,16 @@ namespace moose
132132
{
133133
if (is_writing ())
134134
{
135-
auto const& type = Types::get_polymorphic (instance);
135+
auto const& type = types ().get_polymorphic (instance);
136136
mOutput->write_type_name (type.name ());
137137
return type;
138138
}
139139
else
140140
{
141141
auto const& typeName = mInput->type_name ();
142142
if (typeName.empty ())
143-
return Types::get <T> ();
144-
return Types::get (typeName);
143+
return types ().get <T> ();
144+
return types ().get (typeName);
145145
}
146146
}
147147

@@ -205,21 +205,57 @@ namespace moose
205205
template <class T>
206206
void Archive::archive (const char* name, T& value, EntryTypeDummy <EntryType::Vector>)
207207
{
208+
using Traits = TypeTraits<T>;
209+
using ValueType = typename Traits::ValueType;
210+
211+
constexpr bool unpack = wantsToUnpack<T> () && canBeUnpacked<ValueType> ();
212+
208213
if (is_reading ())
209214
{
210-
TypeTraits<T>::clear (value);
211-
while(mInput->array_has_next (name))
215+
Traits::clear (value);
216+
if constexpr (unpack)
217+
{
218+
while(mInput->array_has_next (name))
219+
{
220+
ValueType childValue;
221+
auto childRange = TypeTraits<ValueType>::toRange (childValue);
222+
for (auto i = childRange.begin; i != childRange.end; ++i)
223+
{
224+
if (!mInput->array_has_next (name))
225+
throw ArchiveError () << "Too few entries while reading range '" << name << "'";
226+
227+
(*this) ("", *i);
228+
}
229+
Traits::pushBack (value, childValue);
230+
}
231+
}
232+
else
212233
{
213-
using ValueType = typename TypeTraits<T>::ValueType;
214-
ValueType tmpVal = detail::GetInitialValue <ValueType> ();
215-
(*this) ("", tmpVal);
216-
TypeTraits<T>::pushBack (value, tmpVal);
234+
while(mInput->array_has_next (name))
235+
{
236+
ValueType tmpVal = detail::GetInitialValue <ValueType> ();
237+
(*this) ("", tmpVal);
238+
Traits::pushBack (value, tmpVal);
239+
}
217240
}
218241
}
219242
else
220243
{
221-
// Writing a vector type is the same as writing a range
222-
archive (name, value, EntryTypeDummy <EntryType::Range> ());
244+
if constexpr (unpack)
245+
{
246+
auto range = Traits::toRange (value);
247+
for (auto i = range.begin; i != range.end; ++i)
248+
{
249+
auto childRange = TypeTraits<ValueType>::toRange (*i);
250+
for (auto j = childRange.begin; j != childRange.end; ++j)
251+
(*this) ("", *j);
252+
}
253+
}
254+
else
255+
{
256+
// Writing a vector type is the same as writing a range
257+
archive (name, value, EntryTypeDummy <EntryType::Range> ());
258+
}
223259
}
224260
}
225261

include/moose/binary_reader.h

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// This file is part of moose, a C++ serialization library
2+
//
3+
// Copyright (C) 2024 Volume Graphics
4+
// All rights reserved.
5+
//
6+
// Redistribution and use in source and binary forms, with or without
7+
// modification, are permitted provided that the following conditions are met:
8+
// * Redistributions of source code must retain the above copyright
9+
// notice, this list of conditions and the following disclaimer.
10+
// * Redistributions in binary form must reproduce the above copyright
11+
// notice, this list of conditions and the following disclaimer in the
12+
// documentation and/or other materials provided with the distribution.
13+
//
14+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16+
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17+
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
18+
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19+
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20+
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21+
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22+
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23+
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24+
#pragma once
25+
26+
#include <moose/export.h>
27+
#include <moose/reader.h>
28+
29+
#include <memory>
30+
#include <stack>
31+
32+
namespace moose
33+
{
34+
class BinaryReader : public Reader {
35+
public:
36+
MOOSE_EXPORT static auto fromFile (const char* filename) -> std::shared_ptr<BinaryReader>;
37+
38+
public:
39+
BinaryReader () = delete;
40+
MOOSE_EXPORT BinaryReader (BinaryReader&& other) = default;
41+
MOOSE_EXPORT BinaryReader (std::istream& in);
42+
MOOSE_EXPORT BinaryReader (std::shared_ptr<std::istream> in);
43+
44+
BinaryReader (BinaryReader const&) = delete;
45+
46+
MOOSE_EXPORT ~BinaryReader () override = default;
47+
48+
BinaryReader& operator = (BinaryReader const&) = delete;
49+
MOOSE_EXPORT BinaryReader& operator = (BinaryReader&& other) = default;
50+
51+
bool begin_entry (const char* name, ContentType type) override;
52+
void end_entry (const char* name, ContentType type) override;
53+
54+
bool array_has_next (const char* name) const override;
55+
56+
auto type_name () const -> std::string override;
57+
auto type_version () const -> Version override;
58+
59+
void read (const char* name, bool& value) const override;
60+
void read (const char* name, double& value) const override;
61+
void read (const char* name, std::string& value) const override;
62+
63+
private:
64+
struct Entry
65+
{
66+
ContentType mType;
67+
bool mArrayHasNext {false};
68+
};
69+
70+
private:
71+
auto current () -> Entry&;
72+
auto current () const -> Entry const&;
73+
bool readArrayHasNext ();
74+
auto in () const -> std::istream&;
75+
76+
private:
77+
std::shared_ptr<std::istream> mStreamStorage;
78+
std::istream* mIn;
79+
std::stack<Entry> mEntries;
80+
};
81+
}// end of namespace moose

include/moose/binary_writer.h

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// This file is part of moose, a C++ serialization library
2+
//
3+
// Copyright (C) 2024 Volume Graphics
4+
// All rights reserved.
5+
//
6+
// Redistribution and use in source and binary forms, with or without
7+
// modification, are permitted provided that the following conditions are met:
8+
// * Redistributions of source code must retain the above copyright
9+
// notice, this list of conditions and the following disclaimer.
10+
// * Redistributions in binary form must reproduce the above copyright
11+
// notice, this list of conditions and the following disclaimer in the
12+
// documentation and/or other materials provided with the distribution.
13+
//
14+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16+
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17+
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
18+
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19+
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20+
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21+
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22+
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23+
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24+
25+
#pragma once
26+
27+
#include <fstream>
28+
#include <stack>
29+
#include <memory>
30+
#include <moose/writer.h>
31+
32+
namespace moose
33+
{
34+
35+
/** Writes binary data to a given stream, using its
36+
`write (const char_type* s, std::streamsize count)` method.
37+
*/
38+
template <class STREAM = std::ofstream>
39+
class BinaryWriter : public Writer
40+
{
41+
public:
42+
static auto toFile (const char* filename) -> std::shared_ptr<BinaryWriter>;
43+
44+
BinaryWriter (STREAM& out);
45+
BinaryWriter (std::shared_ptr<STREAM> out);
46+
47+
BinaryWriter (BinaryWriter const&) = delete;
48+
BinaryWriter (BinaryWriter&& other) = default;
49+
50+
51+
~BinaryWriter () override = default;
52+
53+
BinaryWriter& operator = (BinaryWriter const&) = delete;
54+
BinaryWriter& operator = (BinaryWriter&& other) = default;
55+
56+
bool begin_entry (const char* name, ContentType type, Hint hint) override;
57+
void end_entry (const char* name, ContentType type) override;
58+
59+
void write_type_name (std::string const& typeName) override;
60+
void write_type_version (Version const& version) override;
61+
62+
void write (const char* name, bool value) override;
63+
void write (const char* name, double value) override;
64+
void write (const char* name, std::string const& value) override;
65+
66+
private:
67+
auto out () -> STREAM&;
68+
69+
private:
70+
std::shared_ptr<STREAM> mStreamStorage;
71+
STREAM* mOut;
72+
std::stack<ContentType> mContentStack;
73+
std::stack<std::string> mNameStack;
74+
};
75+
76+
}// end of namespace moose
77+
78+
#include <moose/binary_writer.i>

0 commit comments

Comments
 (0)