-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added versioning to accommodate factor, date(time) changes. (#5)
The specification now has a place to store the version inside the file, so validators can do version-specific tasks. This is motivated by the deprecation of ordered, date and date- types in favor of simplifying the type system. Now, ordered type is just a factor with ordered=true, while the date(time)s are just strings with a special format. This should simplify interpretation a lot.
- Loading branch information
Showing
12 changed files
with
746 additions
and
117 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
#ifndef UZUKI2_PARSED_LIST_HPP | ||
#define UZUKI2_PARSED_LIST_HPP | ||
|
||
#include <memory> | ||
|
||
#include "interfaces.hpp" | ||
#include "Version.hpp" | ||
|
||
/** | ||
* @file ParsedList.hpp | ||
* @brief Class to hold the parsed list. | ||
*/ | ||
|
||
namespace uzuki2 { | ||
|
||
/** | ||
* @brief Results of parsing a list from file. | ||
* | ||
* This wraps a pointer to `Base` and is equivalent to `shared_ptr<Base>` for most applications. | ||
* It contains some extra metadata to hold the version information. | ||
*/ | ||
struct ParsedList { | ||
/** | ||
* @cond | ||
*/ | ||
ParsedList(std::shared_ptr<Base> p, Version v) : version(std::move(v)), ptr(std::move(p)) {} | ||
/** | ||
* @endcond | ||
*/ | ||
|
||
/** | ||
* @return Pointer to `Base`. | ||
*/ | ||
Base* get() const { | ||
return ptr.get(); | ||
} | ||
|
||
/** | ||
* @return Reference to `Base`. | ||
*/ | ||
Base& operator*() const { | ||
return *ptr; | ||
} | ||
|
||
/** | ||
* @return Pointer to `Base`. | ||
*/ | ||
Base* operator->() const { | ||
return ptr.operator->(); | ||
} | ||
|
||
/** | ||
* @return Whether this stores a non-null pointer. | ||
*/ | ||
operator bool() const { | ||
return ptr.operator bool(); | ||
} | ||
|
||
/** | ||
* Calls the corresponding method for `ptr`. | ||
* @tparam Args_ Assorted arguments. | ||
* @param args Arguments forwarded to the corresponding method for `ptr`. | ||
*/ | ||
template<typename ...Args_> | ||
void reset(Args_&& ... args) const { | ||
ptr.reset(std::forward<Args_>(args)...); | ||
} | ||
|
||
/** | ||
* Version of the **uzuki2** specification. | ||
*/ | ||
Version version; | ||
|
||
/** | ||
* Pointer to the `Base` object. | ||
*/ | ||
std::shared_ptr<Base> ptr; | ||
}; | ||
|
||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
#ifndef UZUKI2_VERSIONED_BASE_HPP | ||
#define UZUKI2_VERSIONED_BASE_HPP | ||
|
||
#include <string> | ||
#include <cstring> | ||
|
||
/** | ||
* @file Version.hpp | ||
* @brief Version-related definitions. | ||
*/ | ||
|
||
namespace uzuki2 { | ||
|
||
/** | ||
* @brief Version number. | ||
*/ | ||
struct Version { | ||
/** | ||
* @cond | ||
*/ | ||
Version() = default; | ||
Version(int maj, int min) : major(maj), minor(min) {} | ||
/** | ||
* @endcond | ||
*/ | ||
|
||
/** | ||
* Major version number, must be positive. | ||
*/ | ||
int major = 1; | ||
|
||
/** | ||
* Minor version number, must be non-negative. | ||
*/ | ||
int minor = 0; | ||
|
||
/** | ||
* @param maj Major version number. | ||
* @param min Minor version number. | ||
* @return Whether the version is equal to `<maj>.<min>`. | ||
*/ | ||
bool equals(int maj, int min) const { | ||
return (major == maj && minor == min); | ||
} | ||
}; | ||
|
||
/** | ||
* @cond | ||
*/ | ||
inline Version parse_version_string(const std::string& version_string) { | ||
int major = 0, minor = 0; | ||
size_t i = 0, end = version_string.size(); | ||
|
||
if (version_string.empty()) { | ||
throw std::runtime_error("version string is empty"); | ||
} | ||
if (version_string[i] == '0') { | ||
throw std::runtime_error("invalid version string '" + version_string + "' has leading zeros in its major version"); | ||
} | ||
while (i < end && version_string[i] != '.') { | ||
if (!std::isdigit(version_string[i])) { | ||
throw std::runtime_error("invalid version string '" + version_string + "' contains non-digit characters"); | ||
} | ||
major *= 10; | ||
major += version_string[i] - '0'; | ||
++i; | ||
} | ||
|
||
if (i == end) { | ||
throw std::runtime_error("version string '" + version_string + "' is missing a minor version"); | ||
} | ||
++i; // get past the period and check again. | ||
if (i == end) { | ||
throw std::runtime_error("version string '" + version_string + "' is missing a minor version"); | ||
} | ||
|
||
if (version_string[i] == '0' && i + 1 < end) { | ||
throw std::runtime_error("invalid version string '" + version_string + "' has leading zeros in its minor version"); | ||
} | ||
while (i < end) { | ||
if (!std::isdigit(version_string[i])) { | ||
throw std::runtime_error("invalid version string '" + version_string + "' contains non-digit characters"); | ||
} | ||
minor *= 10; | ||
minor += version_string[i] - '0'; | ||
++i; | ||
} | ||
|
||
return Version(major, minor); | ||
} | ||
/** | ||
* @cond | ||
*/ | ||
|
||
} | ||
|
||
#endif |
Oops, something went wrong.