forked from livegrep/livegrep
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsmart_git.h
109 lines (91 loc) · 2.76 KB
/
smart_git.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/********************************************************************
* livegrep -- smart_git.h
* Copyright (c) 2011-2013 Nelson Elhage
*
* This program is free software. You may use, redistribute, and/or
* modify it under the terms listed in the COPYING file.
********************************************************************/
#ifndef CODESEARCH_SMART_GIT_H
#define CODESEARCH_SMART_GIT_H
#include "git2.h"
class smart_object_base {
public:
smart_object_base() : obj_(0) {
};
operator git_object* () {
return obj_;
}
operator git_object** () {
return &obj_;
}
~smart_object_base() {
if (obj_)
git_object_free(obj_);
}
git_object *release() {
git_object *o = obj_;
obj_ = 0;
return o;
}
protected:
smart_object_base(const smart_object_base& rhs) {
}
git_object *obj_;
};
template <class T>
class object_traits { const static git_otype type; };
template <>
struct object_traits<git_tree> { const static git_otype git_type = GIT_OBJ_TREE; };
template <>
struct object_traits<git_commit> { const static git_otype git_type = GIT_OBJ_COMMIT; };
template <>
struct object_traits<git_blob> { const static git_otype git_type = GIT_OBJ_BLOB; };
template <>
struct object_traits<git_tag> { const static git_otype git_type = GIT_OBJ_TAG; };
template <>
struct object_traits<const git_tree> { const static git_otype git_type = GIT_OBJ_TREE; };
template <>
struct object_traits<const git_commit> { const static git_otype git_type = GIT_OBJ_COMMIT; };
template <>
struct object_traits<const git_blob> { const static git_otype git_type = GIT_OBJ_BLOB; };
template <>
struct object_traits<const git_tag> { const static git_otype git_type = GIT_OBJ_TAG; };
template <class T>
class smart_object : public smart_object_base {
public:
operator T* () {
assert(obj_);
assert(git_object_type(obj_) == object_traits<T>::git_type);
return reinterpret_cast<T*>(obj_);
}
operator T** () {
assert(obj_ == 0);
return reinterpret_cast<T**>(&obj_);
}
T *release() {
T *o = this;
obj_ = 0;
return o;
}
smart_object<T>& operator=(git_object *rhs) {
assert(obj_ == 0);
assert(git_object_type(rhs) == object_traits<T>::git_type);
obj_ = rhs;
return *this;
}
};
template <>
class smart_object <git_object> : public smart_object_base {
public:
template <class O>
operator O* () {
assert(git_object_type(obj_) == object_traits<O>::git_type);
return reinterpret_cast<O*>(obj_);
}
template <class O>
operator O** () {
assert(object_traits<O>::git_type);
return reinterpret_cast<O**>(&obj_);
}
};
#endif /* !defined(CODESEARCH_SMART_GIT_H) */