Commit e9efffff authored by Davis King's avatar Davis King

Made the add_layer variadic constructors take tuples of parameters in addition

to just regular lists of parameters.
parent 1175a7cc
......@@ -12,6 +12,7 @@
#include "../rand.h"
#include "../algs.h"
#include <utility>
#include <tuple>
namespace dlib
......@@ -25,6 +26,50 @@ namespace dlib
// Tell us if T is an instance of add_loss_layer.
template <typename T> struct is_loss_layer_type : std::false_type {};
namespace impl
{
template <size_t... n>
struct ct_integers_list {
template <size_t m>
struct push_back
{
typedef ct_integers_list<n..., m> type;
};
};
template <size_t max>
struct ct_make_integer_range
{
// recursively call push_back on ct_integers_list to build a range from 0 to max
// inclusive.
typedef typename ct_make_integer_range<max-1>::type::template push_back<max>::type type;
};
template <>
struct ct_make_integer_range<0>
{
typedef ct_integers_list<> type;
};
template <size_t... indices, typename Tuple>
auto tuple_subset(
const Tuple& item,
ct_integers_list<indices...>
) -> decltype(std::make_tuple(std::get<indices>(item)...))
{
return std::make_tuple(std::get<indices>(item)...);
}
}
template <typename Head, typename... Tail>
std::tuple<Tail...> tuple_tail(
const std::tuple<Head, Tail...>& item
)
{
return impl::tuple_subset(item, typename impl::ct_make_integer_range<sizeof...(Tail)>::type());
}
// ----------------------------------------------------------------------------------------
inline void randomize_parameters (
......@@ -236,6 +281,32 @@ namespace dlib
{
}
template <typename ...T, typename ...U>
add_layer(
const std::tuple<LAYER_DETAILS,U...>& layer_det,
T&& ...args
) :
details(std::get<0>(layer_det)),
subnetwork(tuple_tail(layer_det),std::forward<T>(args)...),
this_layer_setup_called(false),
gradient_input_is_stale(true)
{
}
template <typename ...T, typename ...U>
add_layer(
std::tuple<>,
const std::tuple<LAYER_DETAILS,U...>& layer_det,
T&& ...args
) : add_layer(layer_det,args...) { }
template <typename ...T>
add_layer(
std::tuple<>,
LAYER_DETAILS&& layer_det,
T&& ...args
) : add_layer(layer_det, args...) { }
template <typename input_iterator>
void to_tensor (
input_iterator ibegin,
......@@ -442,6 +513,31 @@ namespace dlib
gradient_input_is_stale(true)
{}
add_layer(
std::tuple<>,
const LAYER_DETAILS& layer_det
) : add_layer(layer_det) {}
add_layer(
std::tuple<>,
LAYER_DETAILS&& layer_det
) : add_layer(layer_det) {}
add_layer(
std::tuple<>,
LAYER_DETAILS layer_det,
INPUT_LAYER il
) : add_layer(layer_det,il) {}
add_layer(
const std::tuple<LAYER_DETAILS>& layer_det
) : add_layer(std::get<0>(layer_det)) {}
add_layer(
const std::tuple<LAYER_DETAILS>& layer_det,
INPUT_LAYER il
) : add_layer(std::get<0>(layer_det),il) {}
template <typename input_iterator>
void to_tensor (
input_iterator ibegin,
......
......@@ -6,6 +6,7 @@
#include "tensor_abstract.h"
#include <memory>
#include <type_traits>
#include <tuple>
#include "../rand.h"
......@@ -31,6 +32,19 @@ namespace dlib
layer that uses params as its parameters.
!*/
template <
typename Head,
typename... Tail
>
std::tuple<Tail...> tuple_tail(
const std::tuple<Head, Tail...>& item
);
/*!
ensures
- returns a tuple that contains everything in item except for get<0>(item).
So it basically returns make_tuple(get<1>(item),get<2>(item),get<3>(item), and so on).
!*/
// ----------------------------------------------------------------------------------------
template <
......@@ -191,6 +205,17 @@ namespace dlib
- #subnet() == subnet_type(item.subnet())
!*/
template <typename ...T, typename ...U>
add_layer(
const std::tuple<layer_details_type,U...>& layer_det,
T&& ...args
);
/*!
ensures
- #layer_details() == layer_details_type(get<0>(layer_det))
- #subnet() == subnet_type(tuple_tail(layer_det),args)
!*/
template <typename ...T>
add_layer(
const layer_details_type& layer_det,
......
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