Skip to content

Commit 15a88c1

Browse files
committed
ostream checker improved; randomUnique
1 parent 17db9da commit 15a88c1

File tree

3 files changed

+60
-55
lines changed

3 files changed

+60
-55
lines changed

array.h

+45-40
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88

99
namespace impl {
1010

11-
typedef std::pair<size_t, size_t> Range;
12-
1311
template<typename T>
1412
class GenericArray : public Repr<GenericArray<T>>, public std::vector<T> {
1513
public:
@@ -36,10 +34,10 @@ class GenericArray : public Repr<GenericArray<T>>, public std::vector<T> {
3634
using Base::begin;
3735
using Base::end;
3836

39-
static GenericArray<T> random(size_t size, T max);
40-
static GenericArray<T> random(size_t size, T min, T max);
41-
static GenericArray<T> random(const Range& size, T max);
42-
static GenericArray<T> random(const Range& size, T min, T max);
37+
template<typename ...Args>
38+
static GenericArray<T> random(size_t size, const Args& ... args);
39+
template<typename ...Args>
40+
static GenericArray<T> randomUnique(size_t size, const Args& ... args);
4341

4442
static GenericArray<T> id(size_t size, T start = T{});
4543

@@ -69,57 +67,63 @@ class GenericArray : public Repr<GenericArray<T>>, public std::vector<T> {
6967
};
7068

7169
template<typename T>
72-
GenericArray<T> GenericArray<T>::random(size_t size, T max) {
73-
GenericArray<T> result(size);
74-
for (T& x: result) {
75-
x = rnd.next(max);
76-
}
77-
return result;
78-
}
79-
80-
template<typename T>
81-
GenericArray<T> GenericArray<T>::random(size_t size, T min, T max) {
70+
template<typename ...Args>
71+
GenericArray<T> GenericArray<T>::random(size_t size, const Args& ... args) {
8272
GenericArray<T> result(size);
8373
for (T& x: result) {
84-
x = rnd.next(min, max);
74+
x = rnd.next(args...);
8575
}
8676
return result;
8777
}
8878

89-
template<typename T>
90-
GenericArray<T> GenericArray<T>::random(const Range& size, T max) {
91-
return random(rnd.next(size.first, size.second), max);
92-
}
79+
namespace detail {
9380

94-
template<typename T>
95-
GenericArray<T> GenericArray<T>::random(const Range& size, T min, T max) {
96-
return random(rnd.next(size.first, size.second), min, max);
97-
}
81+
template<typename T, typename Enable = std::size_t>
82+
struct DictContainer {
83+
typedef std::set<T> type;
84+
};
9885

9986
template<typename T>
100-
auto genericArrayIdHelper(size_t size, T start)
101-
-> typename std::enable_if<
102-
std::is_integral<T>::value, GenericArray<T>
103-
>::type
87+
struct DictContainer<T, typename std::hash<T>::result_type>
10488
{
105-
GenericArray<T> result(size);
106-
std::iota(result.begin(), result.end(), start);
107-
return result;
108-
}
89+
typedef std::unordered_set<T> type;
90+
};
91+
92+
} // namespace detail
10993

11094
template<typename T>
111-
auto genericArrayIdHelper(size_t size, const T& start)
112-
-> typename std::enable_if<
113-
!std::is_integral<T>::value, GenericArray<T>
114-
>::type
95+
template<typename ...Args>
96+
GenericArray<T> GenericArray<T>::randomUnique(
97+
size_t size, const Args& ... args)
11598
{
116-
ensure("Cannot take GenericArray<T>::id() when T is non-integral");
117-
return {};
99+
typename detail::DictContainer<T>::type set;
100+
std::cerr << "using " << typeid(set).name() << std::endl;
101+
GenericArray<T> result;
102+
result.reserve(size);
103+
104+
while (result.size() != size) {
105+
T t = rnd.next(args...);
106+
if (!set.count(t)) {
107+
set.insert(t);
108+
result.push_back(t);
109+
}
110+
}
111+
112+
return result;
118113
}
119114

120115
template<typename T>
121116
GenericArray<T> GenericArray<T>::id(size_t size, T start) {
122-
return genericArrayIdHelper<T>(size, start);
117+
constexpr bool enable = std::is_integral<T>::value;
118+
static_assert(enable, "Cannot call Array<T>::id with non-integral T");
119+
120+
if (enable) {
121+
GenericArray<T> result(size);
122+
std::iota(result.begin(), result.end(), start);
123+
return result;
124+
} else {
125+
return {};
126+
}
123127
}
124128

125129
template<typename T>
@@ -237,6 +241,7 @@ typedef GenericArray<double> Arrayf;
237241

238242
} // namespace impl
239243

244+
using impl::GenericArray;
240245
using impl::Array;
241246
using impl::Array64;
242247
using impl::Arrayf;

random.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ namespace impl {
66

77
std::mt19937 randomEngine;
88

9-
__attribute__((constructor))
109
static void assertRandomEngineConsistency() {
1110
std::mt19937 engine(1234);
1211
ensure(engine() == 822569775);
@@ -17,6 +16,7 @@ static void assertRandomEngineConsistency() {
1716
class Random {
1817
public:
1918
Random() {
19+
assertRandomEngineConsistency();
2020
randomEngine.seed(std::random_device{}());
2121
}
2222

repr.h

+14-14
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,7 @@ class Repr {
2020
return out;
2121
}
2222

23-
friend T;
24-
25-
// not sure if it would be needed ever
26-
/*
27-
friend Repr<T> repr(const T& t) {
28-
return Repr<T>(t);
29-
}
30-
*/
31-
32-
private:
23+
protected:
3324
Repr() :
3425
object_(nullptr)
3526
{ }
@@ -83,15 +74,24 @@ class Has ## name ## Helper<T,\
8374
detail::Has ## name ## Helper<T>::value
8475

8576
JNGEN_DEFINE_FUNCTION_CHECKER(
86-
Ostream,
77+
OstreamMethod,
8778
std::declval<std::ostream&>().operator<< (std::declval<T>())
8879
)
8980

81+
JNGEN_DEFINE_FUNCTION_CHECKER(
82+
OstreamFreeFunction,
83+
std::operator<<(std::declval<std::ostream&>(), std::declval<T>())
84+
)
85+
9086
JNGEN_DEFINE_FUNCTION_CHECKER(
9187
Plus,
9288
std::declval<T>() + 1
9389
)
9490

91+
#define JNGEN_HAS_OSTREAM()\
92+
(JNGEN_HAS_FUNCTION(OstreamMethod) ||\
93+
JNGEN_HAS_FUNCTION(OstreamFreeFunction))
94+
9595
template<typename T>
9696
struct VectorDepth {
9797
constexpr static int value = 0;
@@ -114,20 +114,20 @@ auto printValue(\
114114
std::ostream& out, const T& t, const OutputModifier& mod, PTag<priority>)\
115115
-> typename std::enable_if<constraint, void>::type
116116

117-
JNGEN_DECLARE_PRINTER(!JNGEN_HAS_FUNCTION(Ostream), 0)
117+
JNGEN_DECLARE_PRINTER(!JNGEN_HAS_OSTREAM(), 0)
118118
{
119119
// can't just write 'false' here because assertion always fails
120120
static_assert(!std::is_same<T, T>::value, "operator<< is undefined");
121121
}
122122

123-
JNGEN_DECLARE_PRINTER(JNGEN_HAS_FUNCTION(Ostream), 1)
123+
JNGEN_DECLARE_PRINTER(JNGEN_HAS_OSTREAM(), 1)
124124
{
125125
(void)mod;
126126
out << t;
127127
}
128128

129129
JNGEN_DECLARE_PRINTER(
130-
JNGEN_HAS_FUNCTION(Ostream) && JNGEN_HAS_FUNCTION(Plus), 2)
130+
JNGEN_HAS_OSTREAM() && JNGEN_HAS_FUNCTION(Plus), 2)
131131
{
132132
out << t + mod.addition;
133133
}

0 commit comments

Comments
 (0)