mirror of
https://github.com/tristanpenman/valijson.git
synced 2024-12-12 10:13:51 +01:00
Allow use of custom alloc/free functions within Subschema class, specifically for allocating memory for Constraints
This commit is contained in:
parent
99455298d8
commit
49fa41ba23
@ -159,14 +159,14 @@ void addRequiredConstraint(Schema &schema)
|
||||
requiredProperties.insert("category");
|
||||
requiredProperties.insert("price");
|
||||
requiredProperties.insert("title");
|
||||
schema.addConstraint(new RequiredConstraint(requiredProperties));
|
||||
schema.addConstraint(RequiredConstraint(requiredProperties));
|
||||
}
|
||||
|
||||
void addTypeConstraint(Schema &schema)
|
||||
{
|
||||
// Add a TypeConstraint to the schema, specifying that the root of the
|
||||
// document must be an object.
|
||||
schema.addConstraint(new TypeConstraint(TypeConstraint::kObject));
|
||||
schema.addConstraint(TypeConstraint(TypeConstraint::kObject));
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
@ -25,9 +25,21 @@ struct BasicConstraint: Constraint
|
||||
return visitor.visit(*static_cast<const ConstraintType*>(this));
|
||||
}
|
||||
|
||||
virtual Constraint * clone() const
|
||||
virtual Constraint * clone(CustomAlloc allocFn, CustomFree freeFn) const
|
||||
{
|
||||
return new ConstraintType(*static_cast<const ConstraintType*>(this));
|
||||
void *ptr = allocFn(sizeof(ConstraintType));
|
||||
if (!ptr) {
|
||||
throw std::runtime_error(
|
||||
"Failed to allocate memory for cloned constraint");
|
||||
}
|
||||
|
||||
try {
|
||||
return new (ptr) ConstraintType(
|
||||
*static_cast<const ConstraintType*>(this));
|
||||
} catch (...) {
|
||||
freeFn(ptr);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -12,7 +12,13 @@ class ConstraintVisitor;
|
||||
*
|
||||
* @todo Consider using something like the boost::cloneable concept here.
|
||||
*/
|
||||
struct Constraint {
|
||||
struct Constraint
|
||||
{
|
||||
/// Typedef for custom new-/malloc-like function
|
||||
typedef void * (*CustomAlloc)(size_t size);
|
||||
|
||||
/// Typedef for custom free-like function
|
||||
typedef void (*CustomFree)(void *);
|
||||
|
||||
/**
|
||||
* @brief Virtual destructor.
|
||||
@ -38,15 +44,10 @@ struct Constraint {
|
||||
*
|
||||
* @returns an owning-pointer to the new constraint.
|
||||
*/
|
||||
virtual Constraint * clone() const = 0;
|
||||
virtual Constraint * clone(CustomAlloc, CustomFree) const = 0;
|
||||
|
||||
};
|
||||
|
||||
inline Constraint * new_clone(const Constraint &constraint)
|
||||
{
|
||||
return constraint.clone();
|
||||
}
|
||||
|
||||
} // namespace constraints
|
||||
} // namespace valijson
|
||||
|
||||
|
@ -25,6 +25,12 @@ namespace valijson {
|
||||
class Subschema
|
||||
{
|
||||
public:
|
||||
/// Typedef for custom new-/malloc-like function
|
||||
typedef void * (*CustomAlloc)(size_t size);
|
||||
|
||||
/// Typedef for custom free-like function
|
||||
typedef void (*CustomFree)(void *);
|
||||
|
||||
/// Typedef the Constraint class into the local namespace for convenience
|
||||
typedef constraints::Constraint Constraint;
|
||||
|
||||
@ -33,9 +39,24 @@ public:
|
||||
typedef boost::function<bool (const Constraint &)> ApplyFunction;
|
||||
|
||||
/**
|
||||
* @brief Construct a new Subschema object with no constraints
|
||||
* @brief Construct a new Subschema object
|
||||
*/
|
||||
Subschema() { }
|
||||
Subschema()
|
||||
: allocFn(::operator new)
|
||||
, freeFn(::operator delete) { }
|
||||
|
||||
/**
|
||||
* @brief Construct a new Subschema using custom memory management
|
||||
* functions
|
||||
*
|
||||
* @parma allocFn malloc- or new-like function to allocate memory
|
||||
* within Schema, such as for Subschema instances
|
||||
* @param freeFn free-like function to free memory allocated with
|
||||
* the `customAlloc` function
|
||||
*/
|
||||
Subschema(CustomAlloc allocFn, CustomFree freeFn)
|
||||
: allocFn(allocFn)
|
||||
, freeFn(freeFn) { }
|
||||
|
||||
/**
|
||||
* @brief Clean up and free all memory managed by the Subschema
|
||||
@ -46,7 +67,8 @@ public:
|
||||
for (std::vector<const Constraint *>::iterator itr =
|
||||
constraints.begin(); itr != constraints.end(); ++itr) {
|
||||
const Constraint *constraint = *itr;
|
||||
delete constraint;
|
||||
constraint->~Constraint();
|
||||
freeFn((void*)(constraint));
|
||||
}
|
||||
constraints.clear();
|
||||
} catch (const std::exception &e) {
|
||||
@ -68,20 +90,7 @@ public:
|
||||
*/
|
||||
void addConstraint(const Constraint &constraint)
|
||||
{
|
||||
constraints.push_back(constraint.clone());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Add a constraint to this sub-schema
|
||||
*
|
||||
* This Subschema instance will take ownership of Constraint that is
|
||||
* pointed to, and will free it when it is no longer needed.
|
||||
*
|
||||
* @param constraint Pointer to the Constraint to take ownership of
|
||||
*/
|
||||
void addConstraint(Constraint *constraint)
|
||||
{
|
||||
constraints.push_back(constraint);
|
||||
constraints.push_back(constraint.clone(allocFn, freeFn));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -239,6 +248,12 @@ public:
|
||||
this->title = title;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
CustomAlloc allocFn;
|
||||
|
||||
CustomFree freeFn;
|
||||
|
||||
private:
|
||||
|
||||
// Disable copy construction
|
||||
|
Loading…
Reference in New Issue
Block a user