<commit_before>/*
 * Copyright (C) 2005-2008 by Dr. <NAME>
 * Copyright (C) 2011 by <NAME>
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * As a special exception, you may use this file as part of a free
 * software library without restriction. Specifically, if other files
 * instantiate templates or use macros or inline functions from this
 * file, or you compile this file and link it with other files to
 * produce an executable, this file does not by itself cause the
 * resulting executable to be covered by the GNU General Public
 * License. This exception does not however invalidate any other
 * reasons why the executable file might be covered by the GNU Library
 * General Public License.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
#ifndef cxxtools_SerializationInfo_h
#define cxxtools_SerializationInfo_h

#include <cxxtools/string.h>
#include <vector>
#include <set>
#include <map>
#include <list>
#include <deque>
#include <limits>
#include <typeinfo>
#include <cxxtools/config.h>

#if __cplusplus >= 201103L

#include <forward_list>
#include <unordered_set>
#include <unordered_map>
#include <utility>

#endif

namespace cxxtools
{

/** @brief Represents arbitrary types during serialization.

    A SerializationInfo represent arbitrary types during serialization. It is
    a flexible structure, which can hold all informations to reconstruct a
    object.

    The types of informations are:

     - a category (Void, Value, Object or Array)
     - a scalar value
     - a name of the type
     - a ordered list of SerializationInfo objects

    Those informations are filled when objects are serialized using a
    serialization operator and a serializer can use those to create a
    serialized representation of a object.

    A deserializer is used to convert a serialized representation into a
    SerializationInfo and a deserialization operator is used to convert the
    SerializationInfo back to the desired object.

    To serialize and deserialize a object, those operators are needed.
    For all standard types there are predefined operators. For user types
    like own classes a operator can easily be written. The signature is
    always the same.

    Serialization operator is defined as:

        void operator <<= (cxxtools::SerializationInfo& si, const YourType& object);

    It must collect all informations from `YourType` and put them to the
    cxxtools::SerializationInfo.

    The deserialization operator is defined as:

        void operator >>= (const cxxtools::SerializationInfo& si, YourType& object);

    It must fetch the informations from SerializationInfo and fill the passed object
    to reconstruct it.

    With those 2 operators a serializer is able to to convert the object to
    some format and the deserializers to convert it back to the object.

    Since for standard container types operators are defined using templates,
    The operators above are also able to serializer and deserialize e.g. a
    `std::vector<YourType>`.

    The scalar value may have several types. When accessing the value it is
    typically converted implicitly when possible. So when e.g. the
    SerializationInfo is set to a numeric value and a string value is read, you
    get a string representation of the numeric value.

 */

class SerializationInfo
{
        typedef std::deque<SerializationInfo> Nodes;
        friend void operator <<=(SerializationInfo& si, const SerializationInfo& ssi);

    public:
        enum Category {
            Void = 0, Value = 1, Object = 2, Array = 6
        };

        /// iterator over subnodes.
        typedef Nodes::iterator Iterator;
        /// const iterator over subnodes.
        typedef Nodes::const_iterator ConstIterator;

        /// iterator over subnodes, std style name.
        typedef Nodes::iterator iterator;
        /// const iterator over subnodes, std style name.
        typedef Nodes::const_iterator const_iterator;

#ifdef HAVE_LONG_LONG
        typedef long long int_type;
#else
        typedef long int_type;
#endif
#ifdef HAVE_UNSIGNED_LONG_LONG
        typedef unsigned long long unsigned_type;
#else
        typedef unsigned long unsigned_type;
#endif

    public:
        SerializationInfo();

        SerializationInfo(const SerializationInfo& si);

        ~SerializationInfo();

        SerializationInfo& operator =(const SerializationInfo& si);

#if __cplusplus >= 201103L

        SerializationInfo(SerializationInfo&& si) noexcept;

        SerializationInfo& operator=(SerializationInfo&& si);

#endif

        Category category() const
        {
            return _category;
        }

        void setCategory(Category cat)
        {
            _category = cat;
        }

        const std::string& typeName() const
        {
            return _type;
        }

        void setTypeName(const std::string& type)
        {
            _type = type;
        }

        const std::string& name() const
        {
            return _name;
        }

        void setName(const std::string& name)
        {
            _name = name;
        }

        /** @brief Serialization of flat data-types
        */
        void setValue(const String& value)       { _setString(value); }
        void setValue(const std::string& value)  { _setString8(value); }
        void setValue(const char* value)         { _setString8(value); }
        void setValue(Char value)                { _setString(String(1, value)); }
        void setValue(wchar_t value)             { _setString(String(1, value)); }
        void setValue(bool value)                { _setBool(value) ; }
        void setValue(char value)                { _setChar(value) ; }
        void setValue(unsigned char value)       { _setUInt(value) ; }
        void setValue(short value)               { _setInt(value) ; }
        void setValue(unsigned short value)      { _setUInt(value) ; }
        void setValue(int value)                 { _setInt(value) ; }
        void setValue(unsigned int value)        { _setUInt(value) ; }
        void setValue(long value)                { _setInt(value) ; }
        void setValue(unsigned long value)       { _setUInt(value) ; }
#ifdef HAVE_LONG_LONG
        void setValue(long long value)           { _setInt(value) ; }<commit_msg>Improve serialization of empty objects with just a type name.<commit_after>/*
 * Copyright (C) 2005-2008 by Dr. <NAME>
 * Copyright (C) 2011 by <NAME>
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * As a special exception, you may use this file as part of a free
 * software library without restriction. Specifically, if other files
 * instantiate templates or use macros or inline functions from this
 * file, or you compile this file and link it with other files to
 * produce an executable, this file does not by itself cause the
 * resulting executable to be covered by the GNU General Public
 * License. This exception does not however invalidate any other
 * reasons why the executable file might be covered by the GNU Library
 * General Public License.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
#ifndef cxxtools_SerializationInfo_h
#define cxxtools_SerializationInfo_h

#include <cxxtools/string.h>
#include <vector>
#include <set>
#include <map>
#include <list>
#include <deque>
#include <limits>
#include <typeinfo>
#include <cxxtools/config.h>

#if __cplusplus >= 201103L

#include <forward_list>
#include <unordered_set>
#include <unordered_map>
#include <utility>

#endif

namespace cxxtools
{

/** @brief Represents arbitrary types during serialization.

    A SerializationInfo represent arbitrary types during serialization. It is
    a flexible structure, which can hold all informations to reconstruct a
    object.

    The types of informations are:

     - a category (Void, Value, Object or Array)
     - a scalar value
     - a name of the type
     - a ordered list of SerializationInfo objects

    Those informations are filled when objects are serialized using a
    serialization operator and a serializer can use those to create a
    serialized representation of a object.

    A deserializer is used to convert a serialized representation into a
    SerializationInfo and a deserialization operator is used to convert the
    SerializationInfo back to the desired object.

    To serialize and deserialize a object, those operators are needed.
    For all standard types there are predefined operators. For user types
    like own classes a operator can easily be written. The signature is
    always the same.

    Serialization operator is defined as:

        void operator <<= (cxxtools::SerializationInfo& si, const YourType& object);

    It must collect all informations from `YourType` and put them to the
    cxxtools::SerializationInfo.

    The deserialization operator is defined as:

        void operator >>= (const cxxtools::SerializationInfo& si, YourType& object);

    It must fetch the informations from SerializationInfo and fill the passed object
    to reconstruct it.

    With those 2 operators a serializer is able to to convert the object to
    some format and the deserializers to convert it back to the object.

    Since for standard container types operators are defined using templates,
    The operators above are also able to serializer and deserialize e.g. a
    `std::vector<YourType>`.

    The scalar value may have several types. When accessing the value it is
    typically converted implicitly when possible. So when e.g. the
    SerializationInfo is set to a numeric value and a string value is read, you
    get a string representation of the numeric value.

 */

class SerializationInfo
{
        typedef std::deque<SerializationInfo> Nodes;
        friend void operator <<=(SerializationInfo& si, const SerializationInfo& ssi);

    public:
        enum Category {
            Void = 0, Value = 1, Object = 2, Array = 6
        };

        /// iterator over subnodes.
        typedef Nodes::iterator Iterator;
        /// const iterator over subnodes.
        typedef Nodes::const_iterator ConstIterator;

        /// iterator over subnodes, std style name.
        typedef Nodes::iterator iterator;
        /// const iterator over subnodes, std style name.
        typedef Nodes::const_iterator const_iterator;

#ifdef HAVE_LONG_LONG
        typedef long long int_type;
#else
        typedef long int_type;
#endif
#ifdef HAVE_UNSIGNED_LONG_LONG
        typedef unsigned long long unsigned_type;
#else
        typedef unsigned long unsigned_type;
#endif

    public:
        SerializationInfo();

        SerializationInfo(const SerializationInfo& si);

        ~SerializationInfo();

        SerializationInfo& operator =(const SerializationInfo& si);

#if __cplusplus >= 201103L

        SerializationInfo(SerializationInfo&& si) noexcept;

        SerializationInfo& operator=(SerializationInfo&& si);

#endif

        Category category() const
        {
            return _category;
        }

        void setCategory(Category cat)
        {
            _category = cat;
        }

        const std::string& typeName() const
        {
            return _type;
        }

        void setTypeName(const std::string& type)
        {
            _type = type;
            if (_category == Void)
                _category = Object;
        }

        const std::string& name() const
        {
            return _name;
        }

        void setName(const std::string& name)
        {
            _name = name;
        }

        /** @brief Serialization of flat data-types
        */
        void setValue(const String& value)       { _setString(value); }
        void setValue(const std::string& value)  { _setString8(value); }
        void setValue(const char* value)         { _setString8(value); }
        void setValue(Char value)                { _setString(String(1, value)); }
        void setValue(wchar_t value)             { _setString(String(1, value)); }
        void setValue(bool value)                { _setBool(value) ; }
        void setValue(char value)                { _setChar(value) ; }
        void setValue(unsigned char value)       { _setUInt(value) ; }
        void setValue(short value)               { _setInt(value) ; }
        void setValue(unsigned short value)      { _setUInt(value) ; }
        void setValue(int value)                 { _setInt(value) ; }
        void setValue(unsigned int value)        { _setUInt(value) ; }
        void setValue(long value)                { _setInt(value) ; }
        void setValue(unsigned long value)       { _setUInt(value) ; }
#ifdef HAVE_LONG_LONG
        void setValue(long long value)           { _setInt(value) ; }
{'fraction_non_alphanumeric': 0.06679075094852889, 'fraction_numerical': 0.006586011883456224, 'mean_word_length': 2.7293112653497063, 'pattern_counts': {'":': 0, '<': 45, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3729736', 'n_tokens_mistral': 3678, 'n_tokens_neox': 3522, 'n_words': 1522}