LCP: Minor improvements
Summary: - Add a unified `generate_lcp` target - Simplify SLK-ERROR and CLONE-ERROR - Rework WITH-VARS - Expect CPP-CLASS, not CPP-TYPE - Fix CPP-TYPE-REFERENCE-P - Add CPP-GENSYM - Add util.lisp to LCP's source files in CMake - Make the CMake variable `lcp_src_files` a cache (persistent) variable - Add `lcp_src_files` as a dependency to `test_lcp` - Rename `lcp_compile` to `compile-lcp` - Fetch docstrings for CPP-NAME-* functions at run-time - Remove existing C++ entities on redefinition Reviewers: mtomic, teon.banek Reviewed By: teon.banek Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D2094
This commit is contained in:
parent
0732264fd5
commit
dbd226d05d
@ -321,6 +321,9 @@ target_compile_definitions(mg-single-node-ha PUBLIC MG_SINGLE_NODE_HA)
|
||||
# END Memgraph Single Node High Availability
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
add_custom_target(generate_lcp)
|
||||
add_dependencies(generate_lcp generate_lcp_single_node generate_lcp_single_node_ha generate_lcp_distributed)
|
||||
|
||||
string(TOLOWER ${CMAKE_BUILD_TYPE} lower_build_type)
|
||||
|
||||
# STATIC library used to store key-value pairs
|
||||
|
@ -3,7 +3,7 @@
|
||||
# Don't forget to repeat this list below in `define_add_lcp`.
|
||||
set(lcp_src_files
|
||||
${CMAKE_SOURCE_DIR}/src/lisp/lcp.asd
|
||||
${CMAKE_SOURCE_DIR}/src/lisp/lcp-compile
|
||||
${CMAKE_SOURCE_DIR}/src/lisp/compile-lcp
|
||||
${CMAKE_SOURCE_DIR}/src/lisp/package.lisp
|
||||
${CMAKE_SOURCE_DIR}/src/lisp/names.lisp
|
||||
${CMAKE_SOURCE_DIR}/src/lisp/types.lisp
|
||||
@ -13,12 +13,17 @@ set(lcp_src_files
|
||||
${CMAKE_SOURCE_DIR}/src/lisp/lcp.lisp
|
||||
${CMAKE_SOURCE_DIR}/src/lisp/debug.lisp
|
||||
${CMAKE_SOURCE_DIR}/src/lisp/test.lisp
|
||||
${CMAKE_SOURCE_DIR}/src/lisp/util.lisp
|
||||
${CMAKE_SOURCE_DIR}/tools/lcp)
|
||||
|
||||
# Make `lcp_src_files` a persistent (cache) variable so that
|
||||
# tests/unit/CMakeLists.txt can see it.
|
||||
set(lcp_src_files "${lcp_src_files}" CACHE INTERNAL "")
|
||||
|
||||
add_custom_target(lcp
|
||||
DEPENDS ${lcp_src_files}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/lcp-compile)
|
||||
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/compile-lcp)
|
||||
|
||||
# Define `add_lcp` function named `name` for registering a lcp file for generation.
|
||||
#
|
||||
@ -53,7 +58,7 @@ macro(define_add_lcp name main_src_files generated_lcp_files)
|
||||
# not visible when invoked in another file.
|
||||
set(lcp_src_files
|
||||
${CMAKE_SOURCE_DIR}/src/lisp/lcp.asd
|
||||
${CMAKE_SOURCE_DIR}/src/lisp/lcp-compile
|
||||
${CMAKE_SOURCE_DIR}/src/lisp/compile-lcp
|
||||
${CMAKE_SOURCE_DIR}/src/lisp/package.lisp
|
||||
${CMAKE_SOURCE_DIR}/src/lisp/names.lisp
|
||||
${CMAKE_SOURCE_DIR}/src/lisp/types.lisp
|
||||
@ -63,6 +68,7 @@ macro(define_add_lcp name main_src_files generated_lcp_files)
|
||||
${CMAKE_SOURCE_DIR}/src/lisp/lcp.lisp
|
||||
${CMAKE_SOURCE_DIR}/src/lisp/debug.lisp
|
||||
${CMAKE_SOURCE_DIR}/src/lisp/test.lisp
|
||||
${CMAKE_SOURCE_DIR}/src/lisp/util.lisp
|
||||
${CMAKE_SOURCE_DIR}/tools/lcp)
|
||||
add_custom_command(OUTPUT ${h_file} ${cpp_file}
|
||||
COMMAND ${CMAKE_SOURCE_DIR}/tools/lcp ${lcp_file} ${slk_serialize}
|
||||
|
@ -1,18 +1,14 @@
|
||||
(in-package #:lcp.clone)
|
||||
|
||||
(define-condition clone-error (error)
|
||||
((message :type string :initarg :message :reader clone-error-message)
|
||||
(format-args :type list :initform nil :initarg :format-args :reader clone-error-format-args))
|
||||
(:report (lambda (condition stream)
|
||||
(apply #'format stream
|
||||
(clone-error-message condition)
|
||||
(clone-error-format-args condition)))))
|
||||
(define-condition clone-error (simple-error)
|
||||
())
|
||||
|
||||
(defun clone-error (message &rest format-args)
|
||||
(error 'clone-error :message message :format-args format-args))
|
||||
(defun clone-error (format-control &rest format-arguments)
|
||||
(error 'clone-error :format-control format-control
|
||||
:format-arguments format-arguments))
|
||||
|
||||
(defun cloning-parent (cpp-class)
|
||||
(check-type cpp-class lcp::cpp-type)
|
||||
(check-type cpp-class lcp::cpp-class)
|
||||
(let ((supers (lcp::cpp-class-super-classes cpp-class))
|
||||
(opts (lcp::cpp-class-clone-opts cpp-class)))
|
||||
(unless opts
|
||||
@ -29,14 +25,14 @@
|
||||
(car supers)))))
|
||||
|
||||
(defun cloning-root (cpp-class)
|
||||
(check-type cpp-class lcp::cpp-type)
|
||||
(check-type cpp-class lcp::cpp-class)
|
||||
(let ((parent-class (cloning-parent cpp-class)))
|
||||
(if parent-class
|
||||
(cloning-root parent-class)
|
||||
cpp-class)))
|
||||
|
||||
(defun members-for-cloning (cpp-class)
|
||||
(check-type cpp-class lcp::cpp-type)
|
||||
(check-type cpp-class lcp::cpp-class)
|
||||
(alexandria:flatten
|
||||
(reverse
|
||||
(loop :for current := cpp-class :then (cloning-parent current)
|
||||
@ -117,7 +113,7 @@
|
||||
(lcp::cpp-type-decl object-type))))))
|
||||
|
||||
(defun clone-vector (elem-type source-name dest-name &key args)
|
||||
(lcp::with-vars ((loop-counter "i"))
|
||||
(lcp::with-cpp-gensyms ((loop-counter "i"))
|
||||
(format nil
|
||||
"~A.resize(~A.size());
|
||||
for (auto ~A = 0; ~A < ~A.size(); ++~A) { ~A }"
|
||||
@ -129,7 +125,8 @@
|
||||
:args args))))
|
||||
|
||||
(defun clone-map (key-type value-type source-name dest-name &key args)
|
||||
(lcp::with-vars ((loop-var "kv") (entry-var "entry"))
|
||||
(lcp::with-cpp-gensyms ((loop-var "kv")
|
||||
(entry-var "entry"))
|
||||
(let ((entry-type (lcp::make-cpp-type
|
||||
"pair"
|
||||
:namespace '("std")
|
||||
@ -146,7 +143,7 @@
|
||||
dest-name entry-var))))
|
||||
|
||||
(defun clone-optional (value-type source-name dest-name &key args)
|
||||
(lcp::with-vars ((value-var "value"))
|
||||
(lcp::with-cpp-gensyms ((value-var "value"))
|
||||
(format nil
|
||||
"if (~A) {
|
||||
~A ~A;
|
||||
@ -165,7 +162,8 @@
|
||||
dest-name)))
|
||||
|
||||
(defun clone-pair (first-type second-type source-name dest-name &key args)
|
||||
(lcp::with-vars ((first-var "first") (second-var "second"))
|
||||
(lcp::with-cpp-gensyms ((first-var "first")
|
||||
(second-var "second"))
|
||||
(with-output-to-string (cpp-out)
|
||||
(lcp::with-cpp-block-output (cpp-out)
|
||||
(format cpp-out
|
||||
|
@ -65,23 +65,72 @@ context which binds OPEN-NAMESPACE-FUN function for opening namespaces."
|
||||
(cl-ppcre:regex-replace-all
|
||||
(string #\Newline) documentation (format nil "~%/// "))))
|
||||
|
||||
(defvar *variable-idx* 0 "Used to generate unique variable names")
|
||||
(defvar *cpp-gensym-counter* 0 "Used to generate unique variable names")
|
||||
|
||||
(defmacro with-vars (vars &body body)
|
||||
"Generates unique variable names for use in generated code by
|
||||
appending an index to desired variable names. Useful when generating
|
||||
loops which might reuse counter names.
|
||||
(defun cpp-gensym (&optional (prefix "var"))
|
||||
"Generate a unique C++ name.
|
||||
|
||||
Usage example:
|
||||
(with-vars ((loop-counter \"i\"))
|
||||
The name is constructed by concatenating the string PREFIX with the current
|
||||
value of *CPP-GENSYM-COUNTER*. Afterwards, the value of *CPP-GENSYM-COUNTER* is
|
||||
incremented by 1.
|
||||
|
||||
Despite the suggestive name \"gensym\", this function cannot guarantee that the
|
||||
name is globally unique (because C++ has no concept equivalent to uninterned
|
||||
symbols). The name is only unique across all of the names generated by the
|
||||
function."
|
||||
(prog1 (format nil "~A~A" prefix *cpp-gensym-counter*)
|
||||
(incf *cpp-gensym-counter*)))
|
||||
|
||||
(defmacro with-cpp-gensyms (vars &body body)
|
||||
"Evaluate and return the result of the implicit progn BODY with the variables
|
||||
specified within VARS bound to strings representing unique C++ names.
|
||||
|
||||
Each element of VARS is either a symbol SYMBOL or a pair (SYMBOL NAME). Bare
|
||||
symbols are equivalent to the pair (SYMBOL SYMBOL-NAME) where SYMBOL-NAME is the
|
||||
result of (cpp-name-for-variable SYMBOL).
|
||||
|
||||
Each pair (SYMBOL NAME) specifies a single unique C++ name. SYMBOL should be a
|
||||
symbol naming the variable to which the generated C++ name will bound. NAME
|
||||
should be a prefix that will be used to construct the name using CPP-GENSYM.
|
||||
|
||||
Example:
|
||||
|
||||
(with-cpp-gensyms ((loop-counter \"i\"))
|
||||
(format nil \"for (auto ~A = 0; ~A < v.size(); ++~A) {
|
||||
// do something
|
||||
}\"
|
||||
loop-counter loop-counter loop-counter))"
|
||||
`(let* ((*variable-idx* (1+ *variable-idx*))
|
||||
,@(loop :for var :in vars :collecting
|
||||
`(,(first var)
|
||||
(format nil "~A~A" ,(second var) *variable-idx*))))
|
||||
loop-counter loop-counter loop-counter))
|
||||
|
||||
;;; >>
|
||||
;;; for (auto i0 = 0; i0 < v.size(); ++i0) {
|
||||
;;; // do something
|
||||
;;; }
|
||||
|
||||
Example:
|
||||
|
||||
Assume *CPP-GENSYM-COUNTER* is 0.
|
||||
|
||||
(defun gen1 ()
|
||||
(with-cpp-gensyms ((hello \"hello\"))
|
||||
(format t \"int ~a;~%\" hello)))
|
||||
|
||||
(defun gen2 ()
|
||||
(with-cpp-gensyms ((hello \"hello\"))
|
||||
(gen1)
|
||||
(format t \"int ~a;~%\" hello)))
|
||||
|
||||
(gen2)
|
||||
|
||||
;;; >>
|
||||
;;; int hello1;
|
||||
;;; int hello0;"
|
||||
`(let* (,@(mapcar
|
||||
(lambda (var)
|
||||
(destructuring-bind (sym &optional name)
|
||||
(alexandria:ensure-list var)
|
||||
(let ((name (or name (cpp-name-for-variable sym))))
|
||||
`(,sym (cpp-gensym ,name)))))
|
||||
vars))
|
||||
,@body))
|
||||
|
||||
(defun cpp-member-reader-name (cpp-member)
|
||||
|
@ -9,4 +9,5 @@ echo \
|
||||
"
|
||||
(load \"${quicklisp_install_dir}/setup.lisp\")
|
||||
(ql:quickload :lcp :silent t)
|
||||
(ql:quickload :lcp/test :silent t)
|
||||
" | sbcl --script
|
@ -154,19 +154,20 @@ The name function's name is of the form CPP-<CPP-OBJECT>-NAME.
|
||||
|
||||
The namestring function's name is of the form
|
||||
ENSURE-NAMESTRING-FOR-<CPP-OBJECT>."
|
||||
`(progn
|
||||
(defun ,(alexandria:symbolicate 'cpp-name-for- cpp-object)
|
||||
(thing &key from-style)
|
||||
,(documentation name-op 'function)
|
||||
(check-type thing (or symbol string))
|
||||
(,name-op thing :from-style from-style))
|
||||
(defun ,(alexandria:symbolicate 'ensure-namestring-for- cpp-object) (thing)
|
||||
,(format nil +cpp-namestring-docstring+
|
||||
(string-downcase cpp-object)
|
||||
(string-downcase cpp-object)
|
||||
name-op)
|
||||
(check-type thing (or symbol string))
|
||||
(ensure-namestring-for thing #',name-op))))
|
||||
(let ((cpp-name-for (alexandria:symbolicate 'cpp-name-for- cpp-object)))
|
||||
`(progn
|
||||
(defun ,cpp-name-for (thing &key from-style)
|
||||
(check-type thing (or symbol string))
|
||||
(,name-op thing :from-style from-style))
|
||||
(setf (documentation ',cpp-name-for 'function)
|
||||
(documentation ',name-op 'function))
|
||||
(defun ,(alexandria:symbolicate 'ensure-namestring-for- cpp-object) (thing)
|
||||
,(format nil +cpp-namestring-docstring+
|
||||
(string-downcase cpp-object)
|
||||
(string-downcase cpp-object)
|
||||
name-op)
|
||||
(check-type thing (or symbol string))
|
||||
(ensure-namestring-for thing #',name-op)))))
|
||||
|
||||
(define-cpp-name namespace lower-snake-case-name)
|
||||
(define-cpp-name class pascal-case-name)
|
||||
|
@ -4,16 +4,12 @@
|
||||
|
||||
(in-package #:lcp.slk)
|
||||
|
||||
(define-condition slk-error (error)
|
||||
((message :type string :initarg :message :reader slk-error-message)
|
||||
(format-args :type list :initform nil :initarg :format-args :reader slk-error-format-args))
|
||||
(:report (lambda (condition stream)
|
||||
(apply #'format stream
|
||||
(slk-error-message condition)
|
||||
(slk-error-format-args condition)))))
|
||||
(define-condition slk-error (simple-error)
|
||||
())
|
||||
|
||||
(defun slk-error (message &rest format-args)
|
||||
(error 'slk-error :message message :format-args format-args))
|
||||
(defun slk-error (format-control &rest format-arguments)
|
||||
(error 'slk-error :format-control format-control
|
||||
:format-arguments format-arguments))
|
||||
|
||||
;;; CPP-CLASS serialization generation
|
||||
|
||||
|
@ -182,8 +182,10 @@ CPP-TYPE-DECL."
|
||||
'(#\Newline)
|
||||
(uiop:run-program "clang-format -style=file" :input s :output '(:string :stripped t)))))
|
||||
|
||||
(defun is-generated (got expected)
|
||||
(is (clang-format got) (clang-format expected) :test #'string=))
|
||||
(defmacro is-generated (got expected)
|
||||
`(is (let ((lcp::*cpp-gensym-counter* 0))
|
||||
(clang-format ,got))
|
||||
(clang-format ,expected) :test #'string=))
|
||||
|
||||
(defun undefine-cpp-types ()
|
||||
(setf lcp::*cpp-classes* nil)
|
||||
@ -784,9 +786,9 @@ CPP-TYPE-DECL."
|
||||
"Filter Clone(ExpressionStorage *exp_storage) const {
|
||||
Filter object;
|
||||
object.expressions_.resize(expressions_.size());
|
||||
for (auto i1 = 0; i1 < expressions_.size(); ++i1) {
|
||||
object.expressions_[i1] =
|
||||
expressions_[i1] ? expressions_[i1]->Clone(exp_storage) : nullptr;
|
||||
for (auto i0 = 0; i0 < expressions_.size(); ++i0) {
|
||||
object.expressions_[i0] =
|
||||
expressions_[i0] ? expressions_[i0]->Clone(exp_storage) : nullptr;
|
||||
}
|
||||
return object;
|
||||
}")))
|
||||
@ -841,15 +843,15 @@ CPP-TYPE-DECL."
|
||||
"object.member_ = member_;")
|
||||
(single-member-test (member "std::vector<Klondike>")
|
||||
"object.member_.resize(member_.size());
|
||||
for (auto i1 = 0; i1 < member_.size(); ++i1) {
|
||||
object.member_[i1] = member_[i1].Clone();
|
||||
for (auto i0 = 0; i0 < member_.size(); ++i0) {
|
||||
object.member_[i0] = member_[i0].Clone();
|
||||
}")
|
||||
(single-member-test (member "std::vector<std::vector<Klondike>>")
|
||||
"object.member_.resize(member_.size());
|
||||
for (auto i1 = 0; i1 < member_.size(); ++i1) {
|
||||
object.member_[i1].resize(member_[i1].size());
|
||||
for (auto i2 = 0; i2 < member_[i1].size(); ++i2) {
|
||||
object.member_[i1][i2] = member_[i1][i2].Clone();
|
||||
for (auto i0 = 0; i0 < member_.size(); ++i0) {
|
||||
object.member_[i0].resize(member_[i0].size());
|
||||
for (auto i1 = 0; i1 < member_[i0].size(); ++i1) {
|
||||
object.member_[i0][i1] = member_[i0][i1].Clone();
|
||||
}
|
||||
}"))
|
||||
(subtest "optional"
|
||||
@ -857,9 +859,9 @@ CPP-TYPE-DECL."
|
||||
"object.member_ = member_;")
|
||||
(single-member-test (member "std::optional<Klondike>")
|
||||
"if (member_) {
|
||||
Klondike value1;
|
||||
value1 = (*member_).Clone();
|
||||
object.member_.emplace(std::move(value1));
|
||||
Klondike value0;
|
||||
value0 = (*member_).Clone();
|
||||
object.member_.emplace(std::move(value0));
|
||||
} else {
|
||||
object.member_ = std::nullopt;
|
||||
}"))
|
||||
@ -869,52 +871,52 @@ CPP-TYPE-DECL."
|
||||
(single-member-test (member "std::unordered_map<int32_t, std::unordered_map<int32_t, std::string>>")
|
||||
"object.member_ = member_;")
|
||||
(single-member-test (member "std::unordered_map<int32_t, Klondike>")
|
||||
"for (const auto &kv1 : member_) {
|
||||
"for (const auto &kv0 : member_) {
|
||||
std::pair<int32_t, Klondike> entry1;
|
||||
{
|
||||
int32_t first2;
|
||||
first2 = kv1.first;
|
||||
Klondike second2;
|
||||
second2 = kv1.second.Clone();
|
||||
entry1 = std::make_pair(std::move(first2), std::move(second2));
|
||||
first2 = kv0.first;
|
||||
Klondike second3;
|
||||
second3 = kv0.second.Clone();
|
||||
entry1 = std::make_pair(std::move(first2), std::move(second3));
|
||||
}
|
||||
|
||||
object.member_.emplace(std::move(entry1));
|
||||
}")
|
||||
(single-member-test (member "std::unordered_map<int32_t, std::unordered_map<int32_t, Klondike>>")
|
||||
"for (const auto &kv1 : member_) {
|
||||
"for (const auto &kv0 : member_) {
|
||||
std::pair<int32_t, std::unordered_map<int32_t, Klondike>> entry1;
|
||||
{
|
||||
int32_t first2;
|
||||
first2 = kv1.first;
|
||||
std::unordered_map<int32_t, Klondike> second2;
|
||||
for (const auto &kv3 : kv1.second) {
|
||||
std::pair<int32_t, Klondike> entry3;
|
||||
first2 = kv0.first;
|
||||
std::unordered_map<int32_t, Klondike> second3;
|
||||
for (const auto &kv4 : kv0.second) {
|
||||
std::pair<int32_t, Klondike> entry5;
|
||||
{
|
||||
int32_t first4;
|
||||
first4 = kv3.first;
|
||||
Klondike second4;
|
||||
second4 = kv3.second.Clone();
|
||||
entry3 = std::make_pair(std::move(first4), std::move(second4));
|
||||
int32_t first6;
|
||||
first6 = kv4.first;
|
||||
Klondike second7;
|
||||
second7 = kv4.second.Clone();
|
||||
entry5 = std::make_pair(std::move(first6), std::move(second7));
|
||||
}
|
||||
|
||||
second2.emplace(std::move(entry3));
|
||||
second3.emplace(std::move(entry5));
|
||||
}
|
||||
entry1 = std::make_pair(std::move(first2), std::move(second2));
|
||||
entry1 = std::make_pair(std::move(first2), std::move(second3));
|
||||
|
||||
}
|
||||
|
||||
object.member_.emplace(std::move(entry1));
|
||||
}")
|
||||
(single-member-test (member "std::unordered_map<Klondike, Klondike>")
|
||||
"for (const auto &kv1 : member_) {
|
||||
"for (const auto &kv0 : member_) {
|
||||
std::pair<Klondike, Klondike> entry1;
|
||||
{
|
||||
Klondike first2;
|
||||
first2 = kv1.first.Clone();
|
||||
Klondike second2;
|
||||
second2 = kv1.second.Clone();
|
||||
entry1 = std::make_pair(std::move(first2), std::move(second2));
|
||||
first2 = kv0.first.Clone();
|
||||
Klondike second3;
|
||||
second3 = kv0.second.Clone();
|
||||
entry1 = std::make_pair(std::move(first2), std::move(second3));
|
||||
}
|
||||
|
||||
object.member_.emplace(std::move(entry1));
|
||||
@ -924,42 +926,42 @@ CPP-TYPE-DECL."
|
||||
"object.member_ = member_;")
|
||||
(single-member-test (member "std::pair<int32_t, Klondike>")
|
||||
"{
|
||||
int32_t first1;
|
||||
first1 = member_.first;
|
||||
int32_t first0;
|
||||
first0 = member_.first;
|
||||
Klondike second1;
|
||||
second1 = member_.second.Clone();
|
||||
object.member_ = std::make_pair(std::move(first1), std::move(second1));
|
||||
object.member_ = std::make_pair(std::move(first0), std::move(second1));
|
||||
}")
|
||||
(single-member-test (member "std::pair<Klondike, int32_t>")
|
||||
"{
|
||||
Klondike first1;
|
||||
first1 = member_.first.Clone();
|
||||
Klondike first0;
|
||||
first0 = member_.first.Clone();
|
||||
int32_t second1;
|
||||
second1 = member_.second;
|
||||
object.member_ = std::make_pair(std::move(first1), std::move(second1));
|
||||
object.member_ = std::make_pair(std::move(first0), std::move(second1));
|
||||
}")
|
||||
(single-member-test (member "std::pair<Klondike, Klondike>")
|
||||
"{
|
||||
Klondike first1;
|
||||
first1 = member_.first.Clone();
|
||||
Klondike first0;
|
||||
first0 = member_.first.Clone();
|
||||
Klondike second1;
|
||||
second1 = member_.second.Clone();
|
||||
object.member_ = std::make_pair(std::move(first1), std::move(second1));
|
||||
object.member_ = std::make_pair(std::move(first0), std::move(second1));
|
||||
}")
|
||||
(single-member-test (member "std::pair<std::string, std::pair<int32_t, Klondike>>")
|
||||
"{
|
||||
std::string first1;
|
||||
first1 = member_.first;
|
||||
std::string first0;
|
||||
first0 = member_.first;
|
||||
std::pair<int32_t, Klondike> second1;
|
||||
{
|
||||
int32_t first2;
|
||||
first2 = member_.second.first;
|
||||
Klondike second2;
|
||||
second2 = member_.second.second.Clone();
|
||||
second1 = std::make_pair(std::move(first2), std::move(second2));
|
||||
Klondike second3;
|
||||
second3 = member_.second.second.Clone();
|
||||
second1 = std::make_pair(std::move(first2), std::move(second3));
|
||||
}
|
||||
|
||||
object.member_ = std::make_pair(std::move(first1), std::move(second1));
|
||||
object.member_ = std::make_pair(std::move(first0), std::move(second1));
|
||||
}"))
|
||||
(subtest "pointers"
|
||||
(single-member-test (member "Klondike *")
|
||||
|
@ -825,7 +825,7 @@ not an instance of UNSUPPORTED-CPP-TYPE)."
|
||||
(defun cpp-type-reference-p (cpp-type)
|
||||
"Test whether CPP-TYPE represents a reference type."
|
||||
(check-type cpp-type cpp-type)
|
||||
(string= (cpp-type-name cpp-type) "*"))
|
||||
(string= (cpp-type-name cpp-type) "&"))
|
||||
|
||||
(defun cpp-type-smart-pointer-p (cpp-type)
|
||||
"Test whether CPP-TYPE represents a smart pointer type."
|
||||
@ -1038,10 +1038,26 @@ defined.")
|
||||
"A list of strings naming the enclosing classes of the current class being
|
||||
defined. The names are ordered from outermost to innermost enclosing class.")
|
||||
|
||||
(defun cons-or-replace (element list &key (test #'eql) (key #'identity))
|
||||
"Cons the ELEMENT to the LIST and remove existing elements.
|
||||
|
||||
All elements that compare equal (under TEST) with ELEMENT are removed. KEY will
|
||||
be applied to each element of LIST before calling TEST."
|
||||
(cons element (remove-if (lambda (other) (funcall test element other))
|
||||
list :key key)))
|
||||
|
||||
(defun register-enum (cpp-enum)
|
||||
"Register the given CPP-ENUM instance with the enum registry."
|
||||
(check-type cpp-enum cpp-enum)
|
||||
(prog1 cpp-enum
|
||||
(push cpp-enum *cpp-enums*)
|
||||
;; Add or redefine the enum.
|
||||
(setf *cpp-enums*
|
||||
(cons cpp-enum
|
||||
(delete-if
|
||||
(lambda (other)
|
||||
(string= (cpp-type-decl cpp-enum) (cpp-type-decl other)))
|
||||
*cpp-enums*)))
|
||||
;; Add to the parent's inner types.
|
||||
(unless (eq *cpp-inner-types* :toplevel)
|
||||
(push cpp-enum *cpp-inner-types*))))
|
||||
|
||||
@ -1050,7 +1066,12 @@ defined. The names are ordered from outermost to innermost enclosing class.")
|
||||
(check-type cpp-class cpp-class)
|
||||
(prog1 cpp-class
|
||||
;; Add or redefine the class.
|
||||
(push cpp-class *cpp-classes*)
|
||||
(setf *cpp-classes*
|
||||
(cons cpp-class
|
||||
(delete-if
|
||||
(lambda (other)
|
||||
(string= (cpp-type-decl cpp-class) (cpp-type-decl other)))
|
||||
*cpp-classes*)))
|
||||
;; Add to the parent's inner types.
|
||||
(unless (eq *cpp-inner-types* :toplevel)
|
||||
(push cpp-class *cpp-inner-types*))))
|
||||
|
@ -378,7 +378,7 @@ target_link_libraries(${test_prefix}auth mg-auth kvstore_lib)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT test_lcp
|
||||
DEPENDS lcp test_lcp.lisp
|
||||
DEPENDS ${lcp_src_files} lcp test_lcp.lisp
|
||||
COMMAND sbcl --script ${CMAKE_CURRENT_SOURCE_DIR}/test_lcp.lisp)
|
||||
add_custom_target(test_lcp ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/test_lcp)
|
||||
add_test(test_lcp ${CMAKE_CURRENT_BINARY_DIR}/test_lcp)
|
||||
|
Loading…
Reference in New Issue
Block a user