Commit 59fcaaff authored by Davis King's avatar Davis King

Reworked the config_reader interface a little to make it easier to use. In

particular, I removed the enumerator over blocks in favor of a simple
get_blocks() function that just returns a std::vector of all the blocks.
I also removed the requires clauses on the block and key accessor functions
and instead made a request for a non-existent key/block result in a non-fatal
exception.  This way users can let the config reader perform a more natural
role in config file validation (by catching this exception and acting accordingly).

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%403077
parent 9ff5b39d
...@@ -31,29 +31,15 @@ namespace dlib ...@@ -31,29 +31,15 @@ namespace dlib
map<std::string,void*>::kernel_1b, map<std::string,void*>::kernel_1b,
tokenizer::kernel_1a tokenizer::kernel_1a
> kernel_1a; > kernel_1a;
// kernel_1a_c
typedef config_reader_kernel_1<
map<std::string,std::string>::kernel_1b,
map<std::string,void*>::kernel_1b,
tokenizer::kernel_1a,
true
> kernel_1a_c;
#ifndef DLIB_ISO_CPP_ONLY #ifndef DLIB_ISO_CPP_ONLY
// thread_safe_1a // thread_safe_1a
typedef config_reader_thread_safe_1< typedef config_reader_thread_safe_1<
kernel_1a, kernel_1a,
map<std::string,void*>::kernel_1b, map<std::string,void*>::kernel_1b
false
> thread_safe_1a; > thread_safe_1a;
// thread_safe_1a_c
typedef config_reader_thread_safe_1<
kernel_1a_c,
map<std::string,void*>::kernel_1b,
true
> thread_safe_1a_c;
#endif // DLIB_ISO_CPP_ONLY #endif // DLIB_ISO_CPP_ONLY
}; };
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include "../algs.h" #include "../algs.h"
#include "../interfaces/enumerable.h" #include "../stl_checked/std_vector_c.h"
namespace dlib namespace dlib
{ {
...@@ -16,13 +16,9 @@ namespace dlib ...@@ -16,13 +16,9 @@ namespace dlib
template < template <
typename map_string_string, typename map_string_string,
typename map_string_void, typename map_string_void,
typename tokenizer, typename tokenizer
bool checking = false
> >
class config_reader_kernel_1 : public enumerable<config_reader_kernel_1<map_string_string, class config_reader_kernel_1
map_string_void,
tokenizer,
checking> >
{ {
/*! /*!
...@@ -35,12 +31,6 @@ namespace dlib ...@@ -35,12 +31,6 @@ namespace dlib
REQUIREMENTS ON tokenizer REQUIREMENTS ON tokenizer
is an implementation of tokenizer/tokenizer_kernel_abstract.h is an implementation of tokenizer/tokenizer_kernel_abstract.h
REQUIREMENTS ON checking
- if (checking == true) then
- The preconditions for this object will be checked.
- else
- The preconditions for this object will NOT be checked.
CONVENTION CONVENTION
key_table.is_in_domain(x) == is_key_defined(x) key_table.is_in_domain(x) == is_key_defined(x)
block_table.is_in_domain(x) == is_block_defined(x) block_table.is_in_domain(x) == is_block_defined(x)
...@@ -75,6 +65,31 @@ namespace dlib ...@@ -75,6 +65,31 @@ namespace dlib
const bool redefinition; const bool redefinition;
}; };
class config_reader_access_error : public dlib::error
{
public:
config_reader_access_error(
const std::string& block_name_,
const std::string& key_name_
) :
dlib::error(ECONFIG_READER),
block_name(block_name_),
key_name(key_name_)
{
std::ostringstream sout;
sout << "Error in config_reader.\n";
if (block_name.size() > 0)
sout << " A block with the name '" << block_name << "' was expected but not found.";
else if (key_name.size() > 0)
sout << " A key with the name '" << key_name << "' was expected but not found.";
const_cast<std::string&>(info) = sout.str();
}
~config_reader_access_error() throw() {}
const std::string block_name;
const std::string key_name;
};
config_reader_kernel_1( config_reader_kernel_1(
std::istream& in std::istream& in
...@@ -114,28 +129,39 @@ namespace dlib ...@@ -114,28 +129,39 @@ namespace dlib
queue_of_strings& keys queue_of_strings& keys
) const; ) const;
inline bool at_start ( template <
) const ; typename alloc
>
inline void reset ( void get_keys (
) const ; std::vector<std::string,alloc>& keys
) const;
inline bool current_element_valid (
) const ;
inline const this_type& element (
) const ;
inline this_type& element ( template <
) ; typename alloc
>
void get_keys (
std_vector_c<std::string,alloc>& keys
) const;
inline bool move_next ( template <
) const ; typename queue_of_strings
>
void get_blocks (
queue_of_strings& blocks
) const;
inline unsigned long size ( template <
) const ; typename alloc
>
void get_blocks (
std::vector<std::string,alloc>& blocks
) const;
inline const std::string& current_block_name ( template <
typename alloc
>
void get_blocks (
std_vector_c<std::string,alloc>& blocks
) const; ) const;
private: private:
...@@ -166,69 +192,6 @@ namespace dlib ...@@ -166,69 +192,6 @@ namespace dlib
}; };
// ----------------------------------------------------------------------------------------
/*
This is a bunch of crap so we can enable and disable the DLIB_CASSERT statements
without getting warnings about conditions always being true or false.
*/
namespace config_reader_kernel_1_helpers
{
template <typename cr_type, bool do_check>
struct helper;
template <typename cr_type>
struct helper<cr_type,false>
{
static void check_operator_bracket_precondition (const cr_type&, const std::string& ) {}
static void check_block_precondition (const cr_type&, const std::string& ) {}
static void check_current_block_name_precondition (const cr_type& ) {}
static void check_element_precondition (const cr_type& ) {}
};
template <typename cr_type>
struct helper<cr_type,true>
{
static void check_operator_bracket_precondition (const cr_type& cr, const std::string& key)
{
DLIB_CASSERT ( cr.is_key_defined(key) == true ,
"\tconst std::string& config_reader::operator[](key)"
<< "\n\tTo access a key's value in the config_reader the key must actually exist."
<< "\n\tkey == " << key
<< "\n\t&cr: " << &cr
);
}
static void check_block_precondition (const cr_type& cr, const std::string& name)
{
DLIB_CASSERT ( cr.is_block_defined(name) == true ,
"\tconst this_type& config_reader::block(name)"
<< "\n\tTo access a sub block in the config_reader the block must actually exist."
<< "\n\tname == " << name
<< "\n\t&cr: " << &cr
);
}
static void check_current_block_name_precondition (const cr_type& cr)
{
DLIB_CASSERT ( cr.current_element_valid() == true ,
"\tconst std::string& config_reader::current_block_name()"
<< "\n\tYou can't call current_block_name() if the current element isn't valid."
<< "\n\t&cr: " << &cr
);
}
static void check_element_precondition (const cr_type& cr)
{
DLIB_CASSERT ( cr.current_element_valid() == true ,
"\tthis_type& config_reader::element()"
<< "\n\tYou can't call element() if the current element isn't valid."
<< "\n\t&cr: " << &cr
);
}
};
}
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// member function definitions // member function definitions
...@@ -238,10 +201,9 @@ namespace dlib ...@@ -238,10 +201,9 @@ namespace dlib
template < template <
typename map_string_string, typename map_string_string,
typename map_string_void, typename map_string_void,
typename tokenizer, typename tokenizer
bool checking
> >
config_reader_kernel_1<map_string_string,map_string_void,tokenizer,checking>:: config_reader_kernel_1<map_string_string,map_string_void,tokenizer>::
config_reader_kernel_1( config_reader_kernel_1(
) )
{ {
...@@ -252,10 +214,9 @@ namespace dlib ...@@ -252,10 +214,9 @@ namespace dlib
template < template <
typename map_string_string, typename map_string_string,
typename map_string_void, typename map_string_void,
typename tokenizer, typename tokenizer
bool checking
> >
void config_reader_kernel_1<map_string_string,map_string_void,tokenizer,checking>:: void config_reader_kernel_1<map_string_string,map_string_void,tokenizer>::
clear( clear(
) )
{ {
...@@ -274,10 +235,9 @@ namespace dlib ...@@ -274,10 +235,9 @@ namespace dlib
template < template <
typename map_string_string, typename map_string_string,
typename map_string_void, typename map_string_void,
typename tokenizer, typename tokenizer
bool checking
> >
void config_reader_kernel_1<map_string_string,map_string_void,tokenizer,checking>:: void config_reader_kernel_1<map_string_string,map_string_void,tokenizer>::
load_from( load_from(
std::istream& in std::istream& in
) )
...@@ -308,10 +268,9 @@ namespace dlib ...@@ -308,10 +268,9 @@ namespace dlib
template < template <
typename map_string_string, typename map_string_string,
typename map_string_void, typename map_string_void,
typename tokenizer, typename tokenizer
bool checking
> >
config_reader_kernel_1<map_string_string,map_string_void,tokenizer,checking>:: config_reader_kernel_1<map_string_string,map_string_void,tokenizer>::
config_reader_kernel_1( config_reader_kernel_1(
std::istream& in std::istream& in
) )
...@@ -324,12 +283,11 @@ namespace dlib ...@@ -324,12 +283,11 @@ namespace dlib
template < template <
typename map_string_string, typename map_string_string,
typename map_string_void, typename map_string_void,
typename tokenizer, typename tokenizer
bool checking
> >
void config_reader_kernel_1<map_string_string,map_string_void,tokenizer,checking>:: void config_reader_kernel_1<map_string_string,map_string_void,tokenizer>::
parse_config_file( parse_config_file(
config_reader_kernel_1<map_string_string,map_string_void,tokenizer,checking>& cr, config_reader_kernel_1<map_string_string,map_string_void,tokenizer>& cr,
tokenizer& tok, tokenizer& tok,
unsigned long& line_number, unsigned long& line_number,
const bool top_of_recursion const bool top_of_recursion
...@@ -477,10 +435,9 @@ namespace dlib ...@@ -477,10 +435,9 @@ namespace dlib
template < template <
typename map_string_string, typename map_string_string,
typename map_string_void, typename map_string_void,
typename tokenizer, typename tokenizer
bool checking
> >
config_reader_kernel_1<map_string_string,map_string_void,tokenizer,checking>:: config_reader_kernel_1<map_string_string,map_string_void,tokenizer>::
~config_reader_kernel_1( ~config_reader_kernel_1(
) )
{ {
...@@ -492,10 +449,9 @@ namespace dlib ...@@ -492,10 +449,9 @@ namespace dlib
template < template <
typename map_string_string, typename map_string_string,
typename map_string_void, typename map_string_void,
typename tokenizer, typename tokenizer
bool checking
> >
bool config_reader_kernel_1<map_string_string,map_string_void,tokenizer,checking>:: bool config_reader_kernel_1<map_string_string,map_string_void,tokenizer>::
is_key_defined ( is_key_defined (
const std::string& key const std::string& key
) const ) const
...@@ -508,10 +464,9 @@ namespace dlib ...@@ -508,10 +464,9 @@ namespace dlib
template < template <
typename map_string_string, typename map_string_string,
typename map_string_void, typename map_string_void,
typename tokenizer, typename tokenizer
bool checking
> >
bool config_reader_kernel_1<map_string_string,map_string_void,tokenizer,checking>:: bool config_reader_kernel_1<map_string_string,map_string_void,tokenizer>::
is_block_defined ( is_block_defined (
const std::string& name const std::string& name
) const ) const
...@@ -524,16 +479,18 @@ namespace dlib ...@@ -524,16 +479,18 @@ namespace dlib
template < template <
typename mss, typename mss,
typename msv, typename msv,
typename tokenizer, typename tokenizer
bool checking
> >
const config_reader_kernel_1<mss,msv,tokenizer,checking>& config_reader_kernel_1<mss,msv,tokenizer,checking>:: const config_reader_kernel_1<mss,msv,tokenizer>& config_reader_kernel_1<mss,msv,tokenizer>::
block ( block (
const std::string& name const std::string& name
) const ) const
{ {
config_reader_kernel_1_helpers::helper<config_reader_kernel_1,checking>:: if (is_block_defined(name) == false)
check_block_precondition(*this,name); {
throw config_reader_access_error(name,"");
}
return *reinterpret_cast<config_reader_kernel_1*>(block_table[name]); return *reinterpret_cast<config_reader_kernel_1*>(block_table[name]);
} }
...@@ -542,16 +499,18 @@ namespace dlib ...@@ -542,16 +499,18 @@ namespace dlib
template < template <
typename map_string_string, typename map_string_string,
typename map_string_void, typename map_string_void,
typename tokenizer, typename tokenizer
bool checking
> >
const std::string& config_reader_kernel_1<map_string_string,map_string_void,tokenizer,checking>:: const std::string& config_reader_kernel_1<map_string_string,map_string_void,tokenizer>::
operator[] ( operator[] (
const std::string& key const std::string& key
) const ) const
{ {
config_reader_kernel_1_helpers::helper<config_reader_kernel_1,checking>:: if (is_key_defined(key) == false)
check_operator_bracket_precondition(*this,key); {
throw config_reader_access_error("",key);
}
return key_table[key]; return key_table[key];
} }
...@@ -560,13 +519,12 @@ namespace dlib ...@@ -560,13 +519,12 @@ namespace dlib
template < template <
typename map_string_string, typename map_string_string,
typename map_string_void, typename map_string_void,
typename tokenizer, typename tokenizer
bool checking
> >
template < template <
typename queue_of_strings typename queue_of_strings
> >
void config_reader_kernel_1<map_string_string,map_string_void,tokenizer,checking>:: void config_reader_kernel_1<map_string_string,map_string_void,tokenizer>::
get_keys ( get_keys (
queue_of_strings& keys queue_of_strings& keys
) const ) const
...@@ -586,29 +544,22 @@ namespace dlib ...@@ -586,29 +544,22 @@ namespace dlib
template < template <
typename map_string_string, typename map_string_string,
typename map_string_void, typename map_string_void,
typename tokenizer, typename tokenizer
bool checking
> >
bool config_reader_kernel_1<map_string_string,map_string_void,tokenizer,checking>::
at_start (
) const
{
return block_table.at_start();
}
// ----------------------------------------------------------------------------------------
template < template <
typename map_string_string, typename alloc
typename map_string_void,
typename tokenizer,
bool checking
> >
void config_reader_kernel_1<map_string_string,map_string_void,tokenizer,checking>:: void config_reader_kernel_1<map_string_string,map_string_void,tokenizer>::
reset ( get_keys (
std::vector<std::string,alloc>& keys
) const ) const
{ {
block_table.reset(); keys.clear();
key_table.reset();
while (key_table.move_next())
{
keys.push_back(key_table.element().key());
}
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -616,48 +567,22 @@ namespace dlib ...@@ -616,48 +567,22 @@ namespace dlib
template < template <
typename map_string_string, typename map_string_string,
typename map_string_void, typename map_string_void,
typename tokenizer, typename tokenizer
bool checking
> >
bool config_reader_kernel_1<map_string_string,map_string_void,tokenizer,checking>::
current_element_valid (
) const
{
return block_table.current_element_valid();
}
// ----------------------------------------------------------------------------------------
template < template <
typename mss, typename alloc
typename msv,
typename tokenizer,
bool checking
> >
const config_reader_kernel_1<mss,msv,tokenizer,checking>& config_reader_kernel_1<mss,msv,tokenizer,checking>:: void config_reader_kernel_1<map_string_string,map_string_void,tokenizer>::
element ( get_keys (
std_vector_c<std::string,alloc>& keys
) const ) const
{ {
config_reader_kernel_1_helpers::helper<config_reader_kernel_1,checking>:: keys.clear();
check_element_precondition(*this); key_table.reset();
return *reinterpret_cast<config_reader_kernel_1*>(block_table.element().value()); while (key_table.move_next())
}
// ----------------------------------------------------------------------------------------
template <
typename mss,
typename msv,
typename tokenizer,
bool checking
>
config_reader_kernel_1<mss,msv,tokenizer,checking>& config_reader_kernel_1<mss,msv,tokenizer,checking>::
element (
)
{ {
config_reader_kernel_1_helpers::helper<config_reader_kernel_1,checking>:: keys.push_back(key_table.element().key());
check_element_precondition(*this); }
return *reinterpret_cast<config_reader_kernel_1*>(block_table.element().value());
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -665,14 +590,24 @@ namespace dlib ...@@ -665,14 +590,24 @@ namespace dlib
template < template <
typename map_string_string, typename map_string_string,
typename map_string_void, typename map_string_void,
typename tokenizer, typename tokenizer
bool checking
> >
bool config_reader_kernel_1<map_string_string,map_string_void,tokenizer,checking>:: template <
move_next ( typename queue_of_strings
>
void config_reader_kernel_1<map_string_string,map_string_void,tokenizer>::
get_blocks (
queue_of_strings& blocks
) const ) const
{ {
return block_table.move_next(); blocks.clear();
block_table.reset();
std::string temp;
while (block_table.move_next())
{
temp = block_table.element().key();
blocks.enqueue(temp);
}
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -680,14 +615,22 @@ namespace dlib ...@@ -680,14 +615,22 @@ namespace dlib
template < template <
typename map_string_string, typename map_string_string,
typename map_string_void, typename map_string_void,
typename tokenizer, typename tokenizer
bool checking >
template <
typename alloc
> >
unsigned long config_reader_kernel_1<map_string_string,map_string_void,tokenizer,checking>:: void config_reader_kernel_1<map_string_string,map_string_void,tokenizer>::
size ( get_blocks (
std::vector<std::string,alloc>& blocks
) const ) const
{ {
return block_table.size(); blocks.clear();
block_table.reset();
while (block_table.move_next())
{
blocks.push_back(block_table.element().key());
}
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -695,16 +638,22 @@ namespace dlib ...@@ -695,16 +638,22 @@ namespace dlib
template < template <
typename map_string_string, typename map_string_string,
typename map_string_void, typename map_string_void,
typename tokenizer, typename tokenizer
bool checking >
template <
typename alloc
> >
const std::string& config_reader_kernel_1<map_string_string,map_string_void,tokenizer,checking>:: void config_reader_kernel_1<map_string_string,map_string_void,tokenizer>::
current_block_name ( get_blocks (
std_vector_c<std::string,alloc>& blocks
) const ) const
{ {
config_reader_kernel_1_helpers::helper<config_reader_kernel_1,checking>:: blocks.clear();
check_current_block_name_precondition(*this); block_table.reset();
return block_table.element().key(); while (block_table.move_next())
{
blocks.push_back(block_table.element().key());
}
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
......
...@@ -5,12 +5,11 @@ ...@@ -5,12 +5,11 @@
#include <string> #include <string>
#include <iosfwd> #include <iosfwd>
#include "../interfaces/enumerable.h"
namespace dlib namespace dlib
{ {
class config_reader : public enumerable<config_reader> class config_reader
{ {
/*! /*!
...@@ -18,11 +17,6 @@ namespace dlib ...@@ -18,11 +17,6 @@ namespace dlib
- there aren't any keys defined for this object - there aren't any keys defined for this object
- there aren't any blocks defined for this object - there aren't any blocks defined for this object
ENUMERATION ORDER
The enumerator will iterate over the sub blocks in the config_reader.
They will be enumerated in sorted order according to the ordering
established on the block names by operator<.
POINTERS AND REFERENCES TO INTERNAL DATA POINTERS AND REFERENCES TO INTERNAL DATA
The destructor, clear(), and load_from() invalidate pointers The destructor, clear(), and load_from() invalidate pointers
and references to internal data. All other functions are guaranteed and references to internal data. All other functions are guaranteed
...@@ -92,7 +86,7 @@ namespace dlib ...@@ -92,7 +86,7 @@ namespace dlib
public: public:
// exception class // exception classes
class config_reader_error : public dlib::error class config_reader_error : public dlib::error
{ {
/*! /*!
...@@ -115,6 +109,28 @@ namespace dlib ...@@ -115,6 +109,28 @@ namespace dlib
const bool redefinition; const bool redefinition;
}; };
class config_reader_access_error : public dlib::error
{
/*!
GENERAL
This exception is thrown if you try to access a key or
block that doesn't exist inside a config reader.
!*/
public:
config_reader_access_error(
const std::string& block_name_,
const std::string& key_name_
);
/*!
ensures
- #block_name == block_name_
- #key_name == key_name_
!*/
const std::string block_name;
const std::string key_name;
};
// -------------------------- // --------------------------
config_reader( config_reader(
...@@ -207,48 +223,64 @@ namespace dlib ...@@ -207,48 +223,64 @@ namespace dlib
const std::string& block_name const std::string& block_name
) const; ) const;
/*! /*!
requires
- is_block_defined(block_name) == true
ensures ensures
- if (is_block_defined(block_name) == true) then
- returns a const reference to the config_reader that represents the given named sub block - returns a const reference to the config_reader that represents the given named sub block
- else
- throws config_reader_access_error
throws
- config_reader_access_error
if this exception is thrown then its block_name field will be set to the
given block_name string.
!*/ !*/
const std::string& operator[] ( const std::string& operator[] (
const std::string& key_name const std::string& key_name
) const; ) const;
/*! /*!
requires
- is_key_defined(key_name) == true
ensures ensures
- if (is_key_defined(key_name) == true) then
- returns a const reference to the value string associated with the given key in - returns a const reference to the value string associated with the given key in
this config_reader's block. this config_reader's block.
- else
- throws config_reader_access_error
throws
- config_reader_access_error
if this exception is thrown then its key_name field will be set to the
given key_name string.
!*/ !*/
template < template <
typename queue_of_strings typename queue_of_strings
// Is an implementation of queue/queue_kernel_abstract.h with T set to std::string
> >
void get_keys ( void get_keys (
queue_of_strings& keys queue_of_strings& keys
) const; ) const;
/*! /*!
requires
- queue_of_strings is an implementation of queue/queue_kernel_abstract.h
with T set to std::string, or std::vector<std::string>, or
dlib::std_vector_c<std::string>
ensures ensures
- #keys == a queue containing all the keys defined in this config_reader's block. - #keys == a queue containing all the keys defined in this config_reader's block.
(i.e. for all strings str in keys it is the case that is_key_defined(str) == true) (i.e. for all strings str in keys it is the case that is_key_defined(str) == true)
throws
- std::bad_alloc
If this exception is thrown then this call has no effect on *this and #keys is
unusable until keys.clear() is called and succeeds.
!*/ !*/
const std::string& current_block_name ( template <
typename queue_of_strings
>
void get_blocks (
queue_of_strings& blocks
) const; ) const;
/*! /*!
requires requires
- current_element_valid() == true - queue_of_strings is an implementation of queue/queue_kernel_abstract.h
with T set to std::string, or std::vector<std::string>, or
dlib::std_vector_c<std::string>
ensures ensures
- returns a string block_name such that: &block(block_name) == &element() - #blocks == a queue containing the names of all the blocks defined in this
(i.e. returns the name of the block that the enumerator is currently at) config_reader's block.
(i.e. for all strings str in blocks it is the case that is_block_defined(str) == true)
!*/ !*/
private: private:
......
...@@ -17,18 +17,17 @@ namespace dlib ...@@ -17,18 +17,17 @@ namespace dlib
template < template <
typename config_reader_base, typename config_reader_base,
typename map_string_void, typename map_string_void
bool checking
> >
class config_reader_thread_safe_1 : public enumerable<config_reader_thread_safe_1<config_reader_base,map_string_void,checking> > class config_reader_thread_safe_1
{ {
/*! /*!
CONVENTION CONVENTION
- get_mutex() == m - get_mutex() == *m
- *cr == the config reader being extended - *cr == the config reader being extended
- block_table[x] == (void*)&block(x) - block_table[x] == (void*)&block(x)
- cr->size == block_table.size() - block_table.size() == the number of blocks in *cr
- block_table[key] == a config_reader_thread_safe_1 that contains &cr.block(key) - block_table[key] == a config_reader_thread_safe_1 that contains &cr.block(key)
- if (own_pointers) then - if (own_pointers) then
- this object owns the m and cr pointers and should delete them when destructed - this object owns the m and cr pointers and should delete them when destructed
...@@ -44,6 +43,7 @@ namespace dlib ...@@ -44,6 +43,7 @@ namespace dlib
config_reader_thread_safe_1(); config_reader_thread_safe_1();
typedef typename config_reader_base::config_reader_error config_reader_error; typedef typename config_reader_base::config_reader_error config_reader_error;
typedef typename config_reader_base::config_reader_access_error config_reader_access_error;
config_reader_thread_safe_1( config_reader_thread_safe_1(
std::istream& in std::istream& in
...@@ -83,28 +83,11 @@ namespace dlib ...@@ -83,28 +83,11 @@ namespace dlib
queue_of_strings& keys queue_of_strings& keys
) const; ) const;
inline bool at_start ( template <
) const ; typename queue_of_strings
>
inline void reset ( void get_blocks (
) const ; queue_of_strings& blocks
inline bool current_element_valid (
) const ;
inline const this_type& element (
) const ;
inline this_type& element (
) ;
inline bool move_next (
) const ;
inline unsigned long size (
) const ;
inline const std::string& current_block_name (
) const; ) const;
inline const rmutex& get_mutex ( inline const rmutex& get_mutex (
...@@ -116,7 +99,7 @@ namespace dlib ...@@ -116,7 +99,7 @@ namespace dlib
); );
/*! /*!
ensures ensures
- block_table.size() == cr->size() - block_table.size() == the number of blocks in cr
- block_table[key] == a config_reader_thread_safe_1 that contains &cr.block(key) - block_table[key] == a config_reader_thread_safe_1 that contains &cr.block(key)
!*/ !*/
...@@ -131,58 +114,6 @@ namespace dlib ...@@ -131,58 +114,6 @@ namespace dlib
}; };
// ----------------------------------------------------------------------------------------
/*
This is a bunch of crap so we can enable and disable the DLIB_CASSERT statements
without getting warnings about conditions always being true or false.
*/
namespace config_reader_thread_safe_1_helpers
{
template <typename cr_type, bool do_check>
struct helper;
template <typename cr_type>
struct helper<cr_type,false>
{
static void check_block_precondition (const cr_type&, const std::string& ) {}
static void check_current_block_name_precondition (const cr_type& ) {}
static void check_element_precondition (const cr_type& ) {}
};
template <typename cr_type>
struct helper<cr_type,true>
{
static void check_block_precondition (const cr_type& cr, const std::string& name)
{
DLIB_CASSERT ( cr.is_block_defined(name) == true ,
"\tconst this_type& config_reader_thread_safe::block(name)"
<< "\n\tTo access a sub block in the config_reader the block must actually exist."
<< "\n\tname == " << name
<< "\n\t&cr: " << &cr
);
}
static void check_current_block_name_precondition (const cr_type& cr)
{
DLIB_CASSERT ( cr.current_element_valid() == true ,
"\tconst std::string& config_reader_thread_safe::current_block_name()"
<< "\n\tYou can't call current_block_name() if the current element isn't valid."
<< "\n\t&cr: " << &cr
);
}
static void check_element_precondition (const cr_type& cr)
{
DLIB_CASSERT ( cr.current_element_valid() == true ,
"\tthis_type& config_reader_thread_safe::element()"
<< "\n\tYou can't call element() if the current element isn't valid."
<< "\n\t&cr: " << &cr
);
}
};
}
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// member function definitions // member function definitions
...@@ -191,10 +122,9 @@ namespace dlib ...@@ -191,10 +122,9 @@ namespace dlib
template < template <
typename config_reader_base, typename config_reader_base,
typename map_string_void, typename map_string_void
bool checking
> >
config_reader_thread_safe_1<config_reader_base,map_string_void,checking>:: config_reader_thread_safe_1<config_reader_base,map_string_void>::
config_reader_thread_safe_1( config_reader_thread_safe_1(
const config_reader_base* base, const config_reader_base* base,
rmutex* m_ rmutex* m_
...@@ -210,10 +140,9 @@ namespace dlib ...@@ -210,10 +140,9 @@ namespace dlib
template < template <
typename config_reader_base, typename config_reader_base,
typename map_string_void, typename map_string_void
bool checking
> >
config_reader_thread_safe_1<config_reader_base,map_string_void,checking>:: config_reader_thread_safe_1<config_reader_base,map_string_void>::
config_reader_thread_safe_1( config_reader_thread_safe_1(
) : ) :
m(0), m(0),
...@@ -237,10 +166,9 @@ namespace dlib ...@@ -237,10 +166,9 @@ namespace dlib
template < template <
typename config_reader_base, typename config_reader_base,
typename map_string_void, typename map_string_void
bool checking
> >
void config_reader_thread_safe_1<config_reader_base,map_string_void,checking>:: void config_reader_thread_safe_1<config_reader_base,map_string_void>::
clear( clear(
) )
{ {
...@@ -253,10 +181,9 @@ namespace dlib ...@@ -253,10 +181,9 @@ namespace dlib
template < template <
typename config_reader_base, typename config_reader_base,
typename map_string_void, typename map_string_void
bool checking
> >
void config_reader_thread_safe_1<config_reader_base,map_string_void,checking>:: void config_reader_thread_safe_1<config_reader_base,map_string_void>::
load_from( load_from(
std::istream& in std::istream& in
) )
...@@ -270,10 +197,9 @@ namespace dlib ...@@ -270,10 +197,9 @@ namespace dlib
template < template <
typename config_reader_base, typename config_reader_base,
typename map_string_void, typename map_string_void
bool checking
> >
config_reader_thread_safe_1<config_reader_base,map_string_void,checking>:: config_reader_thread_safe_1<config_reader_base,map_string_void>::
config_reader_thread_safe_1( config_reader_thread_safe_1(
std::istream& in std::istream& in
) : ) :
...@@ -299,10 +225,9 @@ namespace dlib ...@@ -299,10 +225,9 @@ namespace dlib
template < template <
typename config_reader_base, typename config_reader_base,
typename map_string_void, typename map_string_void
bool checking
> >
config_reader_thread_safe_1<config_reader_base,map_string_void,checking>:: config_reader_thread_safe_1<config_reader_base,map_string_void>::
~config_reader_thread_safe_1( ~config_reader_thread_safe_1(
) )
{ {
...@@ -325,10 +250,9 @@ namespace dlib ...@@ -325,10 +250,9 @@ namespace dlib
template < template <
typename config_reader_base, typename config_reader_base,
typename map_string_void, typename map_string_void
bool checking
> >
bool config_reader_thread_safe_1<config_reader_base,map_string_void,checking>:: bool config_reader_thread_safe_1<config_reader_base,map_string_void>::
is_key_defined ( is_key_defined (
const std::string& key const std::string& key
) const ) const
...@@ -341,10 +265,9 @@ namespace dlib ...@@ -341,10 +265,9 @@ namespace dlib
template < template <
typename config_reader_base, typename config_reader_base,
typename map_string_void, typename map_string_void
bool checking
> >
bool config_reader_thread_safe_1<config_reader_base,map_string_void,checking>:: bool config_reader_thread_safe_1<config_reader_base,map_string_void>::
is_block_defined ( is_block_defined (
const std::string& name const std::string& name
) const ) const
...@@ -357,17 +280,19 @@ namespace dlib ...@@ -357,17 +280,19 @@ namespace dlib
template < template <
typename config_reader_base, typename config_reader_base,
typename map_string_void, typename map_string_void
bool checking
> >
const config_reader_thread_safe_1<config_reader_base,map_string_void,checking>& config_reader_thread_safe_1<config_reader_base,map_string_void,checking>:: const config_reader_thread_safe_1<config_reader_base,map_string_void>& config_reader_thread_safe_1<config_reader_base,map_string_void>::
block ( block (
const std::string& name const std::string& name
) const ) const
{ {
auto_mutex M(*m); auto_mutex M(*m);
config_reader_thread_safe_1_helpers::helper<config_reader_thread_safe_1,checking>:: if (block_table.is_in_domain(name) == false)
check_block_precondition(*this,name); {
throw config_reader_access_error(name,"");
}
return *reinterpret_cast<config_reader_thread_safe_1*>(block_table[name]); return *reinterpret_cast<config_reader_thread_safe_1*>(block_table[name]);
} }
...@@ -375,10 +300,9 @@ namespace dlib ...@@ -375,10 +300,9 @@ namespace dlib
template < template <
typename config_reader_base, typename config_reader_base,
typename map_string_void, typename map_string_void
bool checking
> >
const std::string& config_reader_thread_safe_1<config_reader_base,map_string_void,checking>:: const std::string& config_reader_thread_safe_1<config_reader_base,map_string_void>::
operator[] ( operator[] (
const std::string& key const std::string& key
) const ) const
...@@ -391,13 +315,12 @@ namespace dlib ...@@ -391,13 +315,12 @@ namespace dlib
template < template <
typename config_reader_base, typename config_reader_base,
typename map_string_void, typename map_string_void
bool checking
> >
template < template <
typename queue_of_strings typename queue_of_strings
> >
void config_reader_thread_safe_1<config_reader_base,map_string_void,checking>:: void config_reader_thread_safe_1<config_reader_base,map_string_void>::
get_keys ( get_keys (
queue_of_strings& keys queue_of_strings& keys
) const ) const
...@@ -410,136 +333,27 @@ namespace dlib ...@@ -410,136 +333,27 @@ namespace dlib
template < template <
typename config_reader_base, typename config_reader_base,
typename map_string_void, typename map_string_void
bool checking
>
bool config_reader_thread_safe_1<config_reader_base,map_string_void,checking>::
at_start (
) const
{
auto_mutex M(*m);
return block_table.at_start();
}
// ----------------------------------------------------------------------------------------
template <
typename config_reader_base,
typename map_string_void,
bool checking
>
void config_reader_thread_safe_1<config_reader_base,map_string_void,checking>::
reset (
) const
{
auto_mutex M(*m);
block_table.reset();
}
// ----------------------------------------------------------------------------------------
template <
typename config_reader_base,
typename map_string_void,
bool checking
> >
bool config_reader_thread_safe_1<config_reader_base,map_string_void,checking>::
current_element_valid (
) const
{
auto_mutex M(*m);
return block_table.current_element_valid();
}
// ----------------------------------------------------------------------------------------
template < template <
typename config_reader_base, typename queue_of_strings
typename map_string_void,
bool checking
>
const config_reader_thread_safe_1<config_reader_base,map_string_void,checking>& config_reader_thread_safe_1<config_reader_base,map_string_void,checking>::
element (
) const
{
auto_mutex M(*m);
config_reader_thread_safe_1_helpers::helper<config_reader_thread_safe_1,checking>::
check_element_precondition(*this);
return *reinterpret_cast<config_reader_thread_safe_1*>(block_table.element().value());
}
// ----------------------------------------------------------------------------------------
template <
typename config_reader_base,
typename map_string_void,
bool checking
>
config_reader_thread_safe_1<config_reader_base,map_string_void,checking>& config_reader_thread_safe_1<config_reader_base,map_string_void,checking>::
element (
)
{
auto_mutex M(*m);
config_reader_thread_safe_1_helpers::helper<config_reader_thread_safe_1,checking>::
check_element_precondition(*this);
return *reinterpret_cast<config_reader_thread_safe_1*>(block_table.element().value());
}
// ----------------------------------------------------------------------------------------
template <
typename config_reader_base,
typename map_string_void,
bool checking
>
bool config_reader_thread_safe_1<config_reader_base,map_string_void,checking>::
move_next (
) const
{
auto_mutex M(*m);
return block_table.move_next();
}
// ----------------------------------------------------------------------------------------
template <
typename config_reader_base,
typename map_string_void,
bool checking
>
unsigned long config_reader_thread_safe_1<config_reader_base,map_string_void,checking>::
size (
) const
{
auto_mutex M(*m);
return block_table.size();
}
// ----------------------------------------------------------------------------------------
template <
typename config_reader_base,
typename map_string_void,
bool checking
> >
const std::string& config_reader_thread_safe_1<config_reader_base,map_string_void,checking>:: void config_reader_thread_safe_1<config_reader_base,map_string_void>::
current_block_name ( get_blocks (
queue_of_strings& blocks
) const ) const
{ {
auto_mutex M(*m); auto_mutex M(*m);
config_reader_thread_safe_1_helpers::helper<config_reader_thread_safe_1,checking>:: cr->get_blocks(blocks);
check_current_block_name_precondition(*this);
return block_table.element().key();
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template < template <
typename config_reader_base, typename config_reader_base,
typename map_string_void, typename map_string_void
bool checking
> >
const rmutex& config_reader_thread_safe_1<config_reader_base,map_string_void,checking>:: const rmutex& config_reader_thread_safe_1<config_reader_base,map_string_void>::
get_mutex ( get_mutex (
) const ) const
{ {
...@@ -554,10 +368,9 @@ namespace dlib ...@@ -554,10 +368,9 @@ namespace dlib
template < template <
typename config_reader_base, typename config_reader_base,
typename map_string_void, typename map_string_void
bool checking
> >
void config_reader_thread_safe_1<config_reader_base,map_string_void,checking>:: void config_reader_thread_safe_1<config_reader_base,map_string_void>::
fill_block_table ( fill_block_table (
) )
{ {
...@@ -570,14 +383,15 @@ namespace dlib ...@@ -570,14 +383,15 @@ namespace dlib
} }
block_table.clear(); block_table.clear();
std::vector<std::string> blocks;
cr->get_blocks(blocks);
// now fill the block table up to match what is in cr // now fill the block table up to match what is in cr
cr->reset(); for (unsigned long i = 0; i < blocks.size(); ++i)
while (cr->move_next())
{ {
config_reader_thread_safe_1* block = new config_reader_thread_safe_1(&cr->element(),m); config_reader_thread_safe_1* block = new config_reader_thread_safe_1(&cr->block(blocks[i]),m);
void* temp = block; void* temp = block;
std::string key(cr->current_block_name()); block_table.add(blocks[i],temp);
block_table.add(key,temp);
} }
} }
......
...@@ -19,7 +19,7 @@ namespace dlib ...@@ -19,7 +19,7 @@ namespace dlib
namespace logger_config_file_helpers namespace logger_config_file_helpers
{ {
typedef config_reader::kernel_1a_c cr_type; typedef config_reader::kernel_1a cr_type;
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -122,9 +122,12 @@ namespace dlib ...@@ -122,9 +122,12 @@ namespace dlib
} // if (cr.is_key_defined("output")) } // if (cr.is_key_defined("output"))
// now configure all the sub-blocks // now configure all the sub-blocks
cr.reset(); std_vector_c<std::string> blocks;
while (cr.move_next()) cr.get_blocks(blocks);
configure_sub_blocks(cr.element(), name + "." + cr.current_block_name()); for (unsigned long i = 0; i < blocks.size(); ++i)
{
configure_sub_blocks(cr.block(blocks[i]), name + "." + blocks[i]);
}
} }
...@@ -184,9 +187,12 @@ namespace dlib ...@@ -184,9 +187,12 @@ namespace dlib
} // if (cr.is_key_defined("output")) } // if (cr.is_key_defined("output"))
// now configure all the sub-blocks // now configure all the sub-blocks
cr.reset(); std_vector_c<std::string> blocks;
while (cr.move_next()) cr.get_blocks(blocks);
configure_sub_blocks(cr.element(),cr.current_block_name()); for (unsigned long i = 0; i < blocks.size(); ++i)
{
configure_sub_blocks(cr.block(blocks[i]), blocks[i]);
}
} }
} }
......
...@@ -20,6 +20,10 @@ namespace ...@@ -20,6 +20,10 @@ namespace
using namespace dlib; using namespace dlib;
using namespace std; using namespace std;
// Declare the logger we will use in this test. The name of the tester
// should start with "test."
logger dlog("test.config_reader");
template < template <
typename config_reader typename config_reader
> >
...@@ -31,14 +35,16 @@ namespace ...@@ -31,14 +35,16 @@ namespace
DLIB_TEST(cr.is_block_defined("all")); DLIB_TEST(cr.is_block_defined("all"));
DLIB_TEST(cr.is_key_defined("globalasfd") == false); DLIB_TEST(cr.is_key_defined("globalasfd") == false);
DLIB_TEST(cr.is_block_defined("all!") == false); DLIB_TEST(cr.is_block_defined("all!") == false);
DLIB_TEST(cr.size() == 1);
DLIB_TEST(cr["global"] == "hmm"); DLIB_TEST(cr["global"] == "hmm");
DLIB_TEST(cr["global2"] == "hmm2"); DLIB_TEST(cr["global2"] == "hmm2");
DLIB_TEST(cr.block("all").size() == 4);
DLIB_TEST(cr.block("all").block("block1").size() == 0); std_vector_c<string> blocks;
DLIB_TEST(cr.block("all").block("block2").size() == 0); cr.block("all").get_blocks(blocks);
DLIB_TEST(cr.block("all").block("block3").size() == 0); DLIB_TEST(blocks.size() == 4);
DLIB_TEST(cr.block("all").block("block4").size() == 0); cr.block("all").block("block1").get_blocks(blocks); DLIB_TEST(blocks.size() == 0);
cr.block("all").block("block2").get_blocks(blocks); DLIB_TEST(blocks.size() == 0);
cr.block("all").block("block3").get_blocks(blocks); DLIB_TEST(blocks.size() == 0);
cr.block("all").block("block4").get_blocks(blocks); DLIB_TEST(blocks.size() == 0);
DLIB_TEST(cr.block("all").block("block1").is_key_defined("name")); DLIB_TEST(cr.block("all").block("block1").is_key_defined("name"));
DLIB_TEST(cr.block("all").block("block2").is_key_defined("name")); DLIB_TEST(cr.block("all").block("block2").is_key_defined("name"));
...@@ -59,38 +65,92 @@ namespace ...@@ -59,38 +65,92 @@ namespace
DLIB_TEST(cr.block("all").block("block4")["age"] == "53"); DLIB_TEST(cr.block("all").block("block4")["age"] == "53");
int count1 = 0;
int count2 = 0; int count2 = 0;
while (cr.move_next()) cr.get_blocks(blocks);
{ DLIB_TEST(blocks.size() == 1);
++count1; DLIB_TEST(blocks[0] == "all");
DLIB_TEST(cr.current_block_name() == "all");
DLIB_TEST(cr.element().is_key_defined("global") == false);
DLIB_TEST(cr.element().is_key_defined("global2") == false); DLIB_TEST(cr.block("all").is_key_defined("global") == false);
DLIB_TEST(cr.element().is_key_defined("name") == false); DLIB_TEST(cr.block("all").is_key_defined("global2") == false);
DLIB_TEST(cr.element().is_key_defined("age") == false); DLIB_TEST(cr.block("all").is_key_defined("name") == false);
while (cr.element().move_next()) DLIB_TEST(cr.block("all").is_key_defined("age") == false);
cr.block("all").get_blocks(blocks);
DLIB_TEST(blocks.size() == 4);
std::vector<string> temp_blocks;
for (unsigned long i = 0; i < blocks.size(); ++i)
{ {
++count2; ++count2;
ostringstream sout; ostringstream sout;
sout << "block" << count2; sout << "block" << count2;
DLIB_TEST(cr.element().current_block_name() == sout.str()); DLIB_TEST(blocks[i] == sout.str());
DLIB_TEST(cr.element().size() == 4);
DLIB_TEST(cr.element().element().size() == 0); cr.block("all").block(blocks[i]).get_blocks(temp_blocks);
DLIB_TEST(cr.element().element().is_key_defined("name")); DLIB_TEST(temp_blocks.size() == 0);
DLIB_TEST(cr.element().element().is_key_defined("age"));
DLIB_TEST(cr.block("all").block(blocks[i]).is_key_defined("name"));
DLIB_TEST(cr.block("all").block(blocks[i]).is_key_defined("age"));
} }
bool found_error = false;
try
{
cr.block("bogus_block");
} }
catch (typename config_reader::config_reader_access_error& e)
{
DLIB_TEST(e.block_name == "bogus_block");
DLIB_TEST(e.key_name == "");
found_error = true;
}
DLIB_TEST(found_error);
found_error = false;
try
{
cr["bogus_key"];
}
catch (typename config_reader::config_reader_access_error& e)
{
DLIB_TEST(e.block_name == "");
DLIB_TEST(e.key_name == "bogus_key");
found_error = true;
}
DLIB_TEST(found_error);
DLIB_TEST(count1 == 1);
DLIB_TEST(count2 == 4); found_error = false;
try
{
cr.block("all").block("block10");
}
catch (typename config_reader::config_reader_access_error& e)
{
DLIB_TEST(e.block_name == "block10");
DLIB_TEST(e.key_name == "");
found_error = true;
}
DLIB_TEST(found_error);
found_error = false;
try
{
cr.block("all")["msdofg"];
}
catch (typename config_reader::config_reader_access_error& e)
{
DLIB_TEST(e.block_name == "");
DLIB_TEST(e.key_name == "msdofg");
found_error = true;
}
DLIB_TEST(found_error);
} }
// Declare the logger we will use in this test. The name of the tester
// should start with "test."
logger dlog("test.config_reader");
template < template <
typename config_reader typename config_reader
...@@ -163,7 +223,6 @@ namespace ...@@ -163,7 +223,6 @@ namespace
do_the_tests(cr2); do_the_tests(cr2);
cr.clear(); cr.clear();
DLIB_TEST(cr.size() == 0);
DLIB_TEST(cr.is_key_defined("global") == false); DLIB_TEST(cr.is_key_defined("global") == false);
} }
...@@ -355,17 +414,9 @@ namespace ...@@ -355,17 +414,9 @@ namespace
print_spinner(); print_spinner();
config_reader_test<config_reader::kernel_1a>(); config_reader_test<config_reader::kernel_1a>();
dlog << LINFO << "testing kernel_1a_c";
print_spinner();
config_reader_test<config_reader::kernel_1a_c>();
dlog << LINFO << "testing thread_safe_1a"; dlog << LINFO << "testing thread_safe_1a";
print_spinner(); print_spinner();
config_reader_test<config_reader::thread_safe_1a>(); config_reader_test<config_reader::thread_safe_1a>();
dlog << LINFO << "testing thread_safe_1a_c";
print_spinner();
config_reader_test<config_reader::thread_safe_1a_c>();
} }
} a; } a;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment