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
map<std::string,void*>::kernel_1b,
tokenizer::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
// thread_safe_1a
typedef config_reader_thread_safe_1<
kernel_1a,
map<std::string,void*>::kernel_1b,
false
map<std::string,void*>::kernel_1b
> 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
};
......
......@@ -8,7 +8,7 @@
#include <iostream>
#include <sstream>
#include "../algs.h"
#include "../interfaces/enumerable.h"
#include "../stl_checked/std_vector_c.h"
namespace dlib
{
......@@ -16,13 +16,9 @@ namespace dlib
template <
typename map_string_string,
typename map_string_void,
typename tokenizer,
bool checking = false
typename tokenizer
>
class config_reader_kernel_1 : public enumerable<config_reader_kernel_1<map_string_string,
map_string_void,
tokenizer,
checking> >
class config_reader_kernel_1
{
/*!
......@@ -35,12 +31,6 @@ namespace dlib
REQUIREMENTS ON tokenizer
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
key_table.is_in_domain(x) == is_key_defined(x)
block_table.is_in_domain(x) == is_block_defined(x)
......@@ -75,6 +65,31 @@ namespace dlib
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(
std::istream& in
......@@ -114,28 +129,39 @@ namespace dlib
queue_of_strings& keys
) const;
inline bool at_start (
) const ;
inline void reset (
) const ;
inline bool current_element_valid (
) const ;
inline const this_type& element (
) const ;
template <
typename alloc
>
void get_keys (
std::vector<std::string,alloc>& keys
) const;
inline this_type& element (
) ;
template <
typename alloc
>
void get_keys (
std_vector_c<std::string,alloc>& keys
) const;
inline bool move_next (
) const ;
template <
typename queue_of_strings
>
void get_blocks (
queue_of_strings& blocks
) const;
inline unsigned long size (
) const ;
template <
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;
private:
......@@ -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
......@@ -238,10 +201,9 @@ namespace dlib
template <
typename map_string_string,
typename map_string_void,
typename tokenizer,
bool checking
typename tokenizer
>
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(
)
{
......@@ -252,10 +214,9 @@ namespace dlib
template <
typename map_string_string,
typename map_string_void,
typename tokenizer,
bool checking
typename tokenizer
>
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(
)
{
......@@ -274,10 +235,9 @@ namespace dlib
template <
typename map_string_string,
typename map_string_void,
typename tokenizer,
bool checking
typename tokenizer
>
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(
std::istream& in
)
......@@ -308,10 +268,9 @@ namespace dlib
template <
typename map_string_string,
typename map_string_void,
typename tokenizer,
bool checking
typename tokenizer
>
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(
std::istream& in
)
......@@ -324,12 +283,11 @@ namespace dlib
template <
typename map_string_string,
typename map_string_void,
typename tokenizer,
bool checking
typename tokenizer
>
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(
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,
unsigned long& line_number,
const bool top_of_recursion
......@@ -477,10 +435,9 @@ namespace dlib
template <
typename map_string_string,
typename map_string_void,
typename tokenizer,
bool checking
typename tokenizer
>
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(
)
{
......@@ -492,10 +449,9 @@ namespace dlib
template <
typename map_string_string,
typename map_string_void,
typename tokenizer,
bool checking
typename tokenizer
>
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 (
const std::string& key
) const
......@@ -508,10 +464,9 @@ namespace dlib
template <
typename map_string_string,
typename map_string_void,
typename tokenizer,
bool checking
typename tokenizer
>
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 (
const std::string& name
) const
......@@ -524,16 +479,18 @@ namespace dlib
template <
typename mss,
typename msv,
typename tokenizer,
bool checking
typename tokenizer
>
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 (
const std::string& name
) const
{
config_reader_kernel_1_helpers::helper<config_reader_kernel_1,checking>::
check_block_precondition(*this,name);
if (is_block_defined(name) == false)
{
throw config_reader_access_error(name,"");
}
return *reinterpret_cast<config_reader_kernel_1*>(block_table[name]);
}
......@@ -542,16 +499,18 @@ namespace dlib
template <
typename map_string_string,
typename map_string_void,
typename tokenizer,
bool checking
typename tokenizer
>
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[] (
const std::string& key
) const
{
config_reader_kernel_1_helpers::helper<config_reader_kernel_1,checking>::
check_operator_bracket_precondition(*this,key);
if (is_key_defined(key) == false)
{
throw config_reader_access_error("",key);
}
return key_table[key];
}
......@@ -560,13 +519,12 @@ namespace dlib
template <
typename map_string_string,
typename map_string_void,
typename tokenizer,
bool checking
typename tokenizer
>
template <
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 (
queue_of_strings& keys
) const
......@@ -586,29 +544,22 @@ namespace dlib
template <
typename map_string_string,
typename map_string_void,
typename tokenizer,
bool checking
typename tokenizer
>
bool config_reader_kernel_1<map_string_string,map_string_void,tokenizer,checking>::
at_start (
) const
{
return block_table.at_start();
}
// ----------------------------------------------------------------------------------------
template <
typename map_string_string,
typename map_string_void,
typename tokenizer,
bool checking
typename alloc
>
void config_reader_kernel_1<map_string_string,map_string_void,tokenizer,checking>::
reset (
void config_reader_kernel_1<map_string_string,map_string_void,tokenizer>::
get_keys (
std::vector<std::string,alloc>& keys
) 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
template <
typename map_string_string,
typename map_string_void,
typename tokenizer,
bool checking
typename tokenizer
>
bool config_reader_kernel_1<map_string_string,map_string_void,tokenizer,checking>::
current_element_valid (
) const
{
return block_table.current_element_valid();
}
// ----------------------------------------------------------------------------------------
template <
typename mss,
typename msv,
typename tokenizer,
bool checking
typename alloc
>
const config_reader_kernel_1<mss,msv,tokenizer,checking>& config_reader_kernel_1<mss,msv,tokenizer,checking>::
element (
void config_reader_kernel_1<map_string_string,map_string_void,tokenizer>::
get_keys (
std_vector_c<std::string,alloc>& keys
) const
{
config_reader_kernel_1_helpers::helper<config_reader_kernel_1,checking>::
check_element_precondition(*this);
return *reinterpret_cast<config_reader_kernel_1*>(block_table.element().value());
}
// ----------------------------------------------------------------------------------------
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 (
)
keys.clear();
key_table.reset();
while (key_table.move_next())
{
config_reader_kernel_1_helpers::helper<config_reader_kernel_1,checking>::
check_element_precondition(*this);
return *reinterpret_cast<config_reader_kernel_1*>(block_table.element().value());
keys.push_back(key_table.element().key());
}
}
// ----------------------------------------------------------------------------------------
......@@ -665,14 +590,24 @@ namespace dlib
template <
typename map_string_string,
typename map_string_void,
typename tokenizer,
bool checking
typename tokenizer
>
bool config_reader_kernel_1<map_string_string,map_string_void,tokenizer,checking>::
move_next (
template <
typename queue_of_strings
>
void config_reader_kernel_1<map_string_string,map_string_void,tokenizer>::
get_blocks (
queue_of_strings& blocks
) 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
template <
typename map_string_string,
typename map_string_void,
typename tokenizer,
bool checking
typename tokenizer
>
template <
typename alloc
>
unsigned long config_reader_kernel_1<map_string_string,map_string_void,tokenizer,checking>::
size (
void config_reader_kernel_1<map_string_string,map_string_void,tokenizer>::
get_blocks (
std::vector<std::string,alloc>& blocks
) 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
template <
typename map_string_string,
typename map_string_void,
typename tokenizer,
bool checking
typename tokenizer
>
template <
typename alloc
>
const std::string& config_reader_kernel_1<map_string_string,map_string_void,tokenizer,checking>::
current_block_name (
void config_reader_kernel_1<map_string_string,map_string_void,tokenizer>::
get_blocks (
std_vector_c<std::string,alloc>& blocks
) const
{
config_reader_kernel_1_helpers::helper<config_reader_kernel_1,checking>::
check_current_block_name_precondition(*this);
return block_table.element().key();
blocks.clear();
block_table.reset();
while (block_table.move_next())
{
blocks.push_back(block_table.element().key());
}
}
// ----------------------------------------------------------------------------------------
......
......@@ -5,12 +5,11 @@
#include <string>
#include <iosfwd>
#include "../interfaces/enumerable.h"
namespace dlib
{
class config_reader : public enumerable<config_reader>
class config_reader
{
/*!
......@@ -18,11 +17,6 @@ namespace dlib
- there aren't any keys 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
The destructor, clear(), and load_from() invalidate pointers
and references to internal data. All other functions are guaranteed
......@@ -92,7 +86,7 @@ namespace dlib
public:
// exception class
// exception classes
class config_reader_error : public dlib::error
{
/*!
......@@ -115,6 +109,28 @@ namespace dlib
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(
......@@ -207,48 +223,64 @@ namespace dlib
const std::string& block_name
) const;
/*!
requires
- is_block_defined(block_name) == true
ensures
- if (is_block_defined(block_name) == true) then
- 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& key_name
) const;
/*!
requires
- is_key_defined(key_name) == true
ensures
- if (is_key_defined(key_name) == true) then
- returns a const reference to the value string associated with the given key in
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 <
typename queue_of_strings
// Is an implementation of queue/queue_kernel_abstract.h with T set to std::string
>
void get_keys (
queue_of_strings& keys
) 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
- #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)
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;
/*!
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
- returns a string block_name such that: &block(block_name) == &element()
(i.e. returns the name of the block that the enumerator is currently at)
- #blocks == a queue containing the names of all the blocks defined in this
config_reader's block.
(i.e. for all strings str in blocks it is the case that is_block_defined(str) == true)
!*/
private:
......
......@@ -17,18 +17,17 @@ namespace dlib
template <
typename config_reader_base,
typename map_string_void,
bool checking
typename map_string_void
>
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
- get_mutex() == m
- get_mutex() == *m
- *cr == the config reader being extended
- 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)
- if (own_pointers) then
- this object owns the m and cr pointers and should delete them when destructed
......@@ -44,6 +43,7 @@ namespace dlib
config_reader_thread_safe_1();
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(
std::istream& in
......@@ -83,28 +83,11 @@ namespace dlib
queue_of_strings& keys
) const;
inline bool at_start (
) const ;
inline void reset (
) const ;
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 (
template <
typename queue_of_strings
>
void get_blocks (
queue_of_strings& blocks
) const;
inline const rmutex& get_mutex (
......@@ -116,7 +99,7 @@ namespace dlib
);
/*!
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)
!*/
......@@ -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
......@@ -191,10 +122,9 @@ namespace dlib
template <
typename config_reader_base,
typename map_string_void,
bool checking
typename map_string_void
>
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(
const config_reader_base* base,
rmutex* m_
......@@ -210,10 +140,9 @@ namespace dlib
template <
typename config_reader_base,
typename map_string_void,
bool checking
typename map_string_void
>
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(
) :
m(0),
......@@ -237,10 +166,9 @@ namespace dlib
template <
typename config_reader_base,
typename map_string_void,
bool checking
typename map_string_void
>
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(
)
{
......@@ -253,10 +181,9 @@ namespace dlib
template <
typename config_reader_base,
typename map_string_void,
bool checking
typename map_string_void
>
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(
std::istream& in
)
......@@ -270,10 +197,9 @@ namespace dlib
template <
typename config_reader_base,
typename map_string_void,
bool checking
typename map_string_void
>
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(
std::istream& in
) :
......@@ -299,10 +225,9 @@ namespace dlib
template <
typename config_reader_base,
typename map_string_void,
bool checking
typename map_string_void
>
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(
)
{
......@@ -325,10 +250,9 @@ namespace dlib
template <
typename config_reader_base,
typename map_string_void,
bool checking
typename map_string_void
>
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 (
const std::string& key
) const
......@@ -341,10 +265,9 @@ namespace dlib
template <
typename config_reader_base,
typename map_string_void,
bool checking
typename map_string_void
>
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 (
const std::string& name
) const
......@@ -357,17 +280,19 @@ namespace dlib
template <
typename config_reader_base,
typename map_string_void,
bool checking
typename map_string_void
>
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 (
const std::string& name
) const
{
auto_mutex M(*m);
config_reader_thread_safe_1_helpers::helper<config_reader_thread_safe_1,checking>::
check_block_precondition(*this,name);
if (block_table.is_in_domain(name) == false)
{
throw config_reader_access_error(name,"");
}
return *reinterpret_cast<config_reader_thread_safe_1*>(block_table[name]);
}
......@@ -375,10 +300,9 @@ namespace dlib
template <
typename config_reader_base,
typename map_string_void,
bool checking
typename map_string_void
>
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[] (
const std::string& key
) const
......@@ -391,13 +315,12 @@ namespace dlib
template <
typename config_reader_base,
typename map_string_void,
bool checking
typename map_string_void
>
template <
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 (
queue_of_strings& keys
) const
......@@ -410,136 +333,27 @@ namespace dlib
template <
typename config_reader_base,
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
typename map_string_void
>
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 <
typename config_reader_base,
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
typename queue_of_strings
>
const std::string& config_reader_thread_safe_1<config_reader_base,map_string_void,checking>::
current_block_name (
void config_reader_thread_safe_1<config_reader_base,map_string_void>::
get_blocks (
queue_of_strings& blocks
) const
{
auto_mutex M(*m);
config_reader_thread_safe_1_helpers::helper<config_reader_thread_safe_1,checking>::
check_current_block_name_precondition(*this);
return block_table.element().key();
cr->get_blocks(blocks);
}
// ----------------------------------------------------------------------------------------
template <
typename config_reader_base,
typename map_string_void,
bool checking
typename map_string_void
>
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 (
) const
{
......@@ -554,10 +368,9 @@ namespace dlib
template <
typename config_reader_base,
typename map_string_void,
bool checking
typename map_string_void
>
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 (
)
{
......@@ -570,14 +383,15 @@ namespace dlib
}
block_table.clear();
std::vector<std::string> blocks;
cr->get_blocks(blocks);
// now fill the block table up to match what is in cr
cr->reset();
while (cr->move_next())
for (unsigned long i = 0; i < blocks.size(); ++i)
{
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;
std::string key(cr->current_block_name());
block_table.add(key,temp);
block_table.add(blocks[i],temp);
}
}
......
......@@ -19,7 +19,7 @@ namespace dlib
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
} // if (cr.is_key_defined("output"))
// now configure all the sub-blocks
cr.reset();
while (cr.move_next())
configure_sub_blocks(cr.element(), name + "." + cr.current_block_name());
std_vector_c<std::string> blocks;
cr.get_blocks(blocks);
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
} // if (cr.is_key_defined("output"))
// now configure all the sub-blocks
cr.reset();
while (cr.move_next())
configure_sub_blocks(cr.element(),cr.current_block_name());
std_vector_c<std::string> blocks;
cr.get_blocks(blocks);
for (unsigned long i = 0; i < blocks.size(); ++i)
{
configure_sub_blocks(cr.block(blocks[i]), blocks[i]);
}
}
}
......
......@@ -20,6 +20,10 @@ namespace
using namespace dlib;
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 <
typename config_reader
>
......@@ -31,14 +35,16 @@ namespace
DLIB_TEST(cr.is_block_defined("all"));
DLIB_TEST(cr.is_key_defined("globalasfd") == false);
DLIB_TEST(cr.is_block_defined("all!") == false);
DLIB_TEST(cr.size() == 1);
DLIB_TEST(cr["global"] == "hmm");
DLIB_TEST(cr["global2"] == "hmm2");
DLIB_TEST(cr.block("all").size() == 4);
DLIB_TEST(cr.block("all").block("block1").size() == 0);
DLIB_TEST(cr.block("all").block("block2").size() == 0);
DLIB_TEST(cr.block("all").block("block3").size() == 0);
DLIB_TEST(cr.block("all").block("block4").size() == 0);
std_vector_c<string> blocks;
cr.block("all").get_blocks(blocks);
DLIB_TEST(blocks.size() == 4);
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("block2").is_key_defined("name"));
......@@ -59,38 +65,92 @@ namespace
DLIB_TEST(cr.block("all").block("block4")["age"] == "53");
int count1 = 0;
int count2 = 0;
while (cr.move_next())
{
++count1;
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.element().is_key_defined("name") == false);
DLIB_TEST(cr.element().is_key_defined("age") == false);
while (cr.element().move_next())
cr.get_blocks(blocks);
DLIB_TEST(blocks.size() == 1);
DLIB_TEST(blocks[0] == "all");
DLIB_TEST(cr.block("all").is_key_defined("global") == false);
DLIB_TEST(cr.block("all").is_key_defined("global2") == false);
DLIB_TEST(cr.block("all").is_key_defined("name") == false);
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;
ostringstream sout;
sout << "block" << count2;
DLIB_TEST(cr.element().current_block_name() == sout.str());
DLIB_TEST(cr.element().size() == 4);
DLIB_TEST(cr.element().element().size() == 0);
DLIB_TEST(cr.element().element().is_key_defined("name"));
DLIB_TEST(cr.element().element().is_key_defined("age"));
DLIB_TEST(blocks[i] == sout.str());
cr.block("all").block(blocks[i]).get_blocks(temp_blocks);
DLIB_TEST(temp_blocks.size() == 0);
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 <
typename config_reader
......@@ -163,7 +223,6 @@ namespace
do_the_tests(cr2);
cr.clear();
DLIB_TEST(cr.size() == 0);
DLIB_TEST(cr.is_key_defined("global") == false);
}
......@@ -355,17 +414,9 @@ namespace
print_spinner();
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";
print_spinner();
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;
......
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