Add list template.
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
b45a5d231c
commit
5889c6488f
4 changed files with 113 additions and 1 deletions
|
@ -10,3 +10,6 @@ add_test(format ${CMAKE_CURRENT_BINARY_DIR}/format)
|
|||
add_executable(buffer buffer.cpp)
|
||||
target_link_libraries(buffer ${EXTRA_LIBS})
|
||||
add_test(buffer ${CMAKE_CURRENT_BINARY_DIR}/buffer)
|
||||
add_executable(list list.cpp)
|
||||
target_link_libraries(list ${EXTRA_LIBS})
|
||||
add_test(list ${CMAKE_CURRENT_BINARY_DIR}/list)
|
||||
|
|
|
@ -6,6 +6,7 @@ Author: Leonardo de Moura
|
|||
*/
|
||||
#include <vector>
|
||||
#include "buffer.h"
|
||||
#include "test.h"
|
||||
using namespace lean;
|
||||
|
||||
template<typename C>
|
||||
|
@ -27,6 +28,7 @@ void perftest() {
|
|||
}
|
||||
|
||||
int main() {
|
||||
continue_on_violation(true);
|
||||
loop<buffer<int>>(100);
|
||||
return 0;
|
||||
return has_violations() ? 1 : 0;
|
||||
}
|
||||
|
|
28
src/tests/util/list.cpp
Normal file
28
src/tests/util/list.cpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
Copyright (c) 2013 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
|
||||
Author: Leonardo de Moura
|
||||
*/
|
||||
#include "list.h"
|
||||
#include "test.h"
|
||||
using namespace lean;
|
||||
|
||||
static void tst1() {
|
||||
list<int> l;
|
||||
lean_assert(is_nil(l));
|
||||
for (int i = 0; i < 10; i++) {
|
||||
list<int> old = l;
|
||||
l = list<int>(i, l);
|
||||
lean_assert(!is_nil(l));
|
||||
lean_assert(car(l) == i);
|
||||
lean_assert(cdr(l) == old);
|
||||
}
|
||||
std::cout << l << "\n";
|
||||
}
|
||||
|
||||
int main() {
|
||||
continue_on_violation(true);
|
||||
tst1();
|
||||
return has_violations() ? 1 : 0;
|
||||
}
|
79
src/util/list.h
Normal file
79
src/util/list.h
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
Copyright (c) 2013 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
|
||||
Author: Leonardo de Moura
|
||||
*/
|
||||
#pragma once
|
||||
#include <iostream>
|
||||
#include "rc.h"
|
||||
#include "debug.h"
|
||||
|
||||
namespace lean {
|
||||
/**
|
||||
\brief Basic list template.
|
||||
|
||||
Remark: == is pointer equality.
|
||||
*/
|
||||
template<typename T>
|
||||
class list {
|
||||
struct cell {
|
||||
MK_LEAN_RC()
|
||||
T m_head;
|
||||
list m_tail;
|
||||
cell(T const & h, list const & t):m_rc(1), m_head(h), m_tail(t) {}
|
||||
~cell() {}
|
||||
void dealloc() { delete this; }
|
||||
};
|
||||
cell * m_ptr;
|
||||
public:
|
||||
list():m_ptr(nullptr) {}
|
||||
list(T const & h, list const & t):m_ptr(new cell(h, t)) {}
|
||||
list(list const & s):m_ptr(s.m_ptr) { if (m_ptr) m_ptr->inc_ref(); }
|
||||
list(list&& s):m_ptr(s.m_ptr) { s.m_ptr = 0; }
|
||||
~list() { if (m_ptr) m_ptr->dec_ref(); }
|
||||
|
||||
list & operator=(list const & s) {
|
||||
if (s.m_ptr)
|
||||
s.m_ptr->inc_ref();
|
||||
if (m_ptr)
|
||||
m_ptr->dec_ref();
|
||||
m_ptr = s.m_ptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
list & operator=(list && s) {
|
||||
if (m_ptr)
|
||||
m_ptr->dec_ref();
|
||||
m_ptr = s.m_ptr;
|
||||
s.m_ptr = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend bool is_nil(list const & l) { return l.m_ptr == nullptr; }
|
||||
friend T const & head(list const & l) { lean_assert(!is_nil(l)); return l.m_ptr->m_head; }
|
||||
friend list const & tail(list const & l) { lean_assert(!is_nil(l)); return l.m_ptr->m_tail; }
|
||||
friend bool operator==(list const & l1, list const & l2) { return l1.m_ptr == l2.m_ptr; }
|
||||
friend bool operator!=(list const & l1, list const & l2) { return l1.m_ptr != l2.m_ptr; }
|
||||
};
|
||||
|
||||
template<typename T> inline list<T> cons(T const & h, list<T> const & t) { return list<T>(h, t); }
|
||||
template<typename T> inline T const & car(list<T> const & l) { return head(l); }
|
||||
template<typename T> inline list<T> const & cdr(list<T> const & l) { return tail(l); }
|
||||
|
||||
template<typename T> inline std::ostream & operator<<(std::ostream & out, list<T> const & l) {
|
||||
out << "(";
|
||||
bool first = true;
|
||||
list<T> const * ptr = &l;
|
||||
while (!is_nil(*ptr)) {
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
out << " ";
|
||||
out << head(*ptr);
|
||||
ptr = &tail(*ptr);
|
||||
}
|
||||
out << ")";
|
||||
return out;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue