<
classBase,
classMember>
293 if(
static_cast<void*
>(&
first()) !=
static_cast<void*
>(&
second())){
312 template<
classTEnum>
323 operatorTEnum ()
const{
returnTEnum(
m_Value); }
336 operator unsigned int()
const;
365{
delete[] object; }
403 template<
classX,
classDel = Deleter<X> >
529 template<
classX,
classDel = ArrayDeleter<X> >
642 #ifdef __cpp_using_enum 659 template<
classTValue>
675 template<
classTValue,
classTNullToValue = SThrowOnNull<TValue> >
699 operatorTValue(
void)
const 710 const_cast<TValue&
>(
m_Value) = TNullToValue()();
720*
this= TNullToValue()();
744 template<
classTValue,
classTNullToValue = SThrowOnNull<TValue> >
747 return(
l.IsNull() &&
r.IsNull()) ||
748(!
l.IsNull() && !
r.IsNull() &&
l.GetValue() ==
r.GetValue());
750 template<
classTValue,
classTNullToValue = SThrowOnNull<TValue> >
774 extern char*
strdup(
const char*
str);
790 template<
typenameType>
795 #define ITERATE_CONST(Cont) NCBI_NS_NCBI::s_ITERATE_ConstRef(Cont) 799 template<
typenameType>
802 return&obj1 == &obj2;
804 # define ITERATE_BEGIN(Cont, Begin) \ 805 (NCBI_ASSERT_EXPR(NCBI_NS_NCBI::s_ITERATE_SameObject(Cont, Cont), \ 806 "rvalue container in *ITERATE"), (Cont).Begin())
808 # define ITERATE_BEGIN(Cont, Begin) ((Cont).Begin()) 812 #if 0 && defined(NCBI_HAVE_CXX11) 813 # define ITERATE_VAR(Type) auto 815 # define ITERATE_VAR(Type) Type 819 #define ITERATE(Type, Var, Cont) \ 820 for ( ITERATE_VAR(Type::const_iterator) \ 821 Var = ITERATE_BEGIN(ITERATE_CONST(Cont), begin), \ 822 NCBI_NAME2(Var,_end) = ITERATE_CONST(Cont).end(); \ 823 Var != NCBI_NAME2(Var,_end); ++Var ) 826 #define NON_CONST_ITERATE(Type, Var, Cont) \ 827 for ( ITERATE_VAR(Type::iterator) Var = ITERATE_BEGIN(Cont, begin); \ 828 Var != (Cont).end(); ++Var ) 831 #define REVERSE_ITERATE(Type, Var, Cont) \ 832 for ( ITERATE_VAR(Type::const_reverse_iterator) \ 833 Var = ITERATE_BEGIN(ITERATE_CONST(Cont), rbegin), \ 834 NCBI_NAME2(Var,_end) = ITERATE_CONST(Cont).rend(); \ 835 Var != NCBI_NAME2(Var,_end); ++Var ) 838 #define NON_CONST_REVERSE_ITERATE(Type, Var, Cont) \ 839 for ( ITERATE_VAR(Type::reverse_iterator) \ 840 Var = ITERATE_BEGIN(Cont, rbegin); \ 841 Var != (Cont).rend(); ++Var ) 847 #define ERASE_ITERATE(Type, Var, Cont) \ 848 for ( ITERATE_VAR(Type::iterator) Var = ITERATE_BEGIN(Cont, begin), \ 849 NCBI_NAME2(Var,_next) = Var; \ 850 (Var = NCBI_NAME2(Var,_next)) != (Cont).end() && \ 851 (++NCBI_NAME2(Var,_next), true); ) 856 #define VECTOR_ERASE(Var, Cont) (NCBI_NAME2(Var,_next) = (Cont).erase(Var)) 865 #define ITERATE_BOTH_BOOL_VALUES(BoolVar) \ 866 for( bool BoolVar##BOTH_BOOL_VALUES_DONE##__LINE__ = false, BoolVar = false; ! BoolVar##BOTH_BOOL_VALUES_DONE##__LINE__ ; BoolVar##BOTH_BOOL_VALUES_DONE##__LINE__ = BoolVar, BoolVar = true ) 869 #define ITERATE_0_IDX(idx, up_to) \ 870 for( TSeqPos idx = 0; idx < up_to; ++idx ) 873 #define ITERATE_SIMPLE(num_iters) \ 874 ITERATE_0_IDX( _dummy_idx_94768308_##__LINE__, num_iters ) 895 template<
classTKey,
classTStorage>
929 #if !defined(NCBI_TEST_APPLICATION) 930 template<
typenameT>
934 template<
typenameT>
936 template<
typenameT>
938 template<
typenameT>
941 operator T(
void)
const{
return static_cast<T>(
m_Id); }
948 template<
classTKey,
classTStorage>
952 return out<<
id.Get();
955 template<
classTKey,
classTStorage>
974 #if defined(NCBI_INT4_GI) 976 # error "Both NCBI_INT4_GI and NCBI_INT8_GI must not be defined!" 978 # ifdef NCBI_STRICT_GI 979 # error "Both NCBI_INT4_GI and NCBI_STRICT_GI must not be defined!" 981 #elif !defined(NCBI_INT8_GI) 982 # define NCBI_INT8_GI 985 #ifdef NCBI_TEST_STRICT_ENTREZ_ID 987 #define NCBI_STRICT_ENTREZ_ID 990 # ifdef NCBI_STRICT_ENTREZ_ID 991 # undef NCBI_STRICT_ENTREZ_ID 995 #ifndef NCBI_STRICT_GI 996 # undef NCBI_STRICT_ENTREZ_ID 997 # undef NCBI_STRICT_TAX_ID 1027 #ifdef NCBI_STRICT_GI 1042 #ifdef NCBI_STRICT_ENTREZ_ID 1049 #ifdef NCBI_STRICT_TAX_ID 1057 template<
classTId, TId
id>
1060 #ifndef NCBI_COMPILER_MSVC 1065 static constTId
value= id;
1069 #ifdef NCBI_STRICT_GI 1072 #define STRICT_ID_TO(TId, TInt, id) (static_cast<TInt>((id).Get())) 1073 #define STRICT_ID_FROM(TIdType, TIntType, id) (TIdType(static_cast<TIdType::TId>(id))) 1074 #define STRICT_ID_CONST(type, id) \ 1075 (type(static_cast<type::TId>(ncbi::CConstIdChecker<type::TId, id>::value))) 1076 #define STRICT_ID_ZERO(type) STRICT_ID_CONST(type, 0) 1077 #define STRICT_ID_INVALID(type) STRICT_ID_CONST(type, -1) 1081 #define STRICT_ID_TO(TId, TInt, id) (static_cast<TInt>(id)) 1082 #define STRICT_ID_FROM(TIdType, TIntType, id) (static_cast<TIdType>(id)) 1083 #define STRICT_ID_CONST(type, id) (ncbi::CConstIdChecker<type, id>::value) 1084 #define STRICT_ID_ZERO(type) type(0) 1085 #define STRICT_ID_INVALID(type) type(-1) 1089 #define GI_TO(T, gi) STRICT_ID_TO(ncbi::TGi, T, gi) 1090 #define GI_FROM(T, value) STRICT_ID_FROM(ncbi::TGi, T, value) 1091 #define GI_CONST(gi) STRICT_ID_CONST(ncbi::TGi, gi) 1092 #define ZERO_GI STRICT_ID_ZERO(ncbi::TGi) 1093 #define INVALID_GI STRICT_ID_INVALID(ncbi::TGi) 1096 #ifdef NCBI_STRICT_ENTREZ_ID 1097 # define ENTREZ_ID_TO(T, entrez_id) STRICT_ID_TO(ncbi::TEntrezId, T, entrez_id) 1098 # define ENTREZ_ID_FROM(T, value) STRICT_ID_FROM(ncbi::TEntrezId, T, value) 1099 # define ENTREZ_ID_CONST(id) STRICT_ID_CONST(ncbi::TEntrezId, id) 1101 # define ENTREZ_ID_TO(T, entrez_id) (static_cast<T>(entrez_id)) 1102 # define ENTREZ_ID_FROM(T, value) (static_cast<ncbi::TEntrezId>(value)) 1103 # define ENTREZ_ID_CONST(id) id 1106 #define ZERO_ENTREZ_ID ENTREZ_ID_CONST(0) 1107 #define INVALID_ENTREZ_ID ENTREZ_ID_CONST(-1) 1109 #ifdef NCBI_STRICT_TAX_ID 1110 # define TAX_ID_TO(T, tax_id) STRICT_ID_TO(ncbi::TTaxId, T, tax_id) 1111 # define TAX_ID_FROM(T, value) STRICT_ID_FROM(ncbi::TTaxId, T, value) 1112 # define TAX_ID_CONST(id) STRICT_ID_CONST(ncbi::TTaxId, id) 1114 # define TAX_ID_TO(T, tax_id) (static_cast<T>(tax_id)) 1115 # define TAX_ID_FROM(T, value) (static_cast<ncbi::TTaxId>(value)) 1116 # define TAX_ID_CONST(id) id 1119 #define ZERO_TAX_ID TAX_ID_CONST(0) 1120 #define INVALID_TAX_ID TAX_ID_CONST(-1) 1124 #define INT_ID_TO(T, id) (static_cast<T>(id)) 1125 #define INT_ID_FROM(T, value) (static_cast<ncbi::TIntId>(value)) 1143 return static_cast<char*
>(object) +
offset;
1149 return static_cast<const char*
>(object) +
offset;
1156(
static_cast<const char*
>(
first) -
static_cast<const char*
>(second));
1168 template<
size_tKEmbeddedSize,
classTType =
char>
1210 #if defined(NCBI_COMPILER_MSVC) || defined(NCBI_COMPILER_VISUALAGE) 1211 # define NCBI_DEPRECATED_CTOR(decl) NCBI_DEPRECATED decl 1213 # define NCBI_DEPRECATED_CTOR(decl) decl NCBI_DEPRECATED 1219 #define NCBI_DEPRECATED_CLASS NCBI_DEPRECATED_CTOR(class) 1224 # undef NCBI_DEPRECATED_CTOR 1225 # undef NCBI_DEPRECATED_CLASS 1226 # define NCBI_DEPRECATED_CTOR(decl) decl __attribute__((deprecated)) 1227 # define NCBI_DEPRECATED_CLASS class __attribute__((deprecated)) 1231 #ifdef NCBI_ENABLE_SAFE_FLAGS 1262 template<
classEnum>
1291 return get() ==
b.get();
1295 return get() !=
b.get();
1351 #define DECLARE_SAFE_FLAGS_TYPE(E, T) \ 1352 typedef NCBI_NS_NCBI::CSafeFlags<E> T 1359 #define DECLARE_SAFE_FLAGS(E) \ 1360 inline NCBI_NS_NCBI::CSafeFlags<E> operator|(E a, E b) \ 1361 { return NCBI_NS_NCBI::CSafeFlags<E>(a) | b; } \ 1362 inline NCBI_NS_NCBI::CSafeFlags<E> operator&(E a, E b) \ 1363 { return NCBI_NS_NCBI::CSafeFlags<E>(a) & b; } \ 1364 inline NCBI_NS_NCBI::CSafeFlags<E> operator^(E a, E b) \ 1365 { return NCBI_NS_NCBI::CSafeFlags<E>(a) ^ b; } \ 1366 inline NCBI_NS_NCBI::CSafeFlags<E> operator~(E a) \ 1367 { return ~NCBI_NS_NCBI::CSafeFlags<E>(a); } 1384 template<
classE>
inline 1392 # define DECLARE_SAFE_FLAGS_TYPE(Enum,Typedef) typedef underlying_type<Enum>::type Typedef 1393 # define DECLARE_SAFE_FLAGS(Enum) NCBI_EAT_SEMICOLON(safe_flags) 1416 catch(exception& e) {
1417 ERR_POST(
"Error executing action: "<< e.what());
1456 template<
classT,
classU = conditional_t<is_po
inter_v<T>, remove_po
inter_t<T>, T>>
1460 template<
classT,
typenameTDeleter>
1482 #define NCBI_EXPORT_FUNC_DECLARE(lib, func) \ 1483 namespace NCBI_ ## lib \ 1485 namespace S ## func \ 1487 using T = decltype(func); \ 1489 NCBI_ ## lib ## _EXPORT T* F(); \ 1491 template <class T> \ 1494 template <class TR, class... TArgs> \ 1495 struct S<TR (TArgs...)> \ 1497 static TR Call(TArgs... args) { return F()(args...); } \ 1501 constexpr auto func = S ## func::S<S ## func::T>::Call; \ 1504 #define NCBI_EXPORT_FUNC_DEFINE(lib, func) \ 1505 namespace NCBI_ ## lib \ 1507 namespace S ## func \ 1509 T* F() { return ::func; } \ 1519 template<
classT1,
classT2>
1521 void swap(NCBI_NS_NCBI::pair_base_member<T1,T2>& pair1,
1522NCBI_NS_NCBI::pair_base_member<T1,T2>& pair2)
1528 template<
classP,
classD>
1530 void swap(NCBI_NS_NCBI::AutoPtr<P,D>& ptr1,
1531NCBI_NS_NCBI::AutoPtr<P,D>& ptr2)
1537 #if defined(NCBI_COMPILER_WORKSHOP) || defined(NCBI_COMPILER_MIPSPRO) 1539 #define ArraySize(array) (sizeof(array)/sizeof((array)[0])) 1543 template<
classElement,
size_tSize>
1550 #ifdef NCBI_STRICT_GI 1553 size_t operator()(
constncbi::CStrictId<TKey, TStorage> & x)
const 1559 # if __has_include(<format>) 1560 template<
classTKey,
classTStorage,
classTChar>
1562:
publicformatter<TStorage, TChar>
1564 typedefncbi::CStrictId<TKey, TStorage>
TId;
1566 template<
classTFmtContext>
1567TFmtContext::iterator
format(
constTId&
id, TFmtContext&
ctx)
const{
Template used to replace bool type arguments with some strict equivalent.
a helper template to enforce constness of argument to GI_CONST macro
CNcbiActionGuard class Executes registered callbacks on request or on destruction.
Template class allowing to store a value or null (unassigned) state.
Support for safe enum flags.
Template class for strict ID types.
definition of a Culling tree
Template used for empty base class optimization.
std::ofstream out("events_result.xml")
main entry point for tests
static DLIST_TYPE *DLIST_NAME() first(DLIST_LIST_TYPE *list)
static const char * str(char *buf, int n)
element_type * m_Ptr
Internal pointer representation.
TValue operator()(void) const
virtual ~CNcbiActionGuard(void)
SStrictId_Entrez::TId TEntrezId
TEntrezId type for entrez ids which require the same strictness as TGi.
const Type & s_ITERATE_ConstRef(const Type &obj)
NCBI_XNCBI_EXPORT void g_ThrowOnNull(void)
Del deleter_type
Alias for template argument.
#define DECLARE_OPERATOR_BOOL(Expr)
Declaration of safe bool operator from boolean expression.
~AutoPtr(void)
Destructor.
CNcbiActionGuard & operator=(const CNcbiActionGuard &)
ETriState
Enumeration to represent a tristate value.
CSafeFlags operator~() const
AutoPtr< X, Del > & operator=(const AutoPtr< X, Del > &p)
Assignment operator.
CNcbiOstream & operator<<(CNcbiOstream &out, const CStrictId< TKey, TStorage > &id)
void AddAction(TFunc func)
element_type & operator[](size_t pos)
Array style dereference (returns reference)
CAction_Base & operator=(const CAction_Base &)
X element_type
Define element type.
CSafeFlags & operator|=(const CSafeFlags &b)
enum ENcbiSwitch ESwitch
Aux.
CStrictId(T id, typename enable_if< is_same< T, TId >::value, T >::type=0)
element_type * x_Release(void) const
Release for const object.
void reset(element_type *p=0, EOwnership ownership=eTakeOwnership)
Reset will delete the old pointer (if owned), set content to the new value, and assume the ownership ...
void ExecuteActions(void)
bool operator!=(const CNullable< TValue, TNullToValue > &l, const CNullable< TValue, TNullToValue > &r)
constexpr CSafeFlags(storage_type flags)
char * strdup(const char *str)
Supply string duplicate function, if one is not defined.
AutoPtr(const AutoPtr< X, Del > &p)
Copy constructor.
unique_ptr< U, void(*)(U *)> c_unique_ptr
Template helpers for unique_ptr to work with resource allocating/deallocating C functions.
bool operator==(const CSafeFlags &b) const
CSafeFlags operator&(const CSafeFlags &b) const
pair_base_member(const first_type &first_value, const second_type &second_value)
ERetriable
Can the action be retried?
void Swap(AutoPtr< X, Del > &a)
CAction_Base(const CAction_Base &)
void Swap(pair_base_member< first_type, second_type > &p)
pair_base_member< deleter_type, bool > m_Data
State info.
AutoArray< X, Del > & operator=(element_type *p)
Assignment operator.
CSafeFlags< E > operator|(E a, CSafeFlags< E > b)
Helper operators for safe-flags enums.
bool operator!=(const CSafeFlags &b) const
bool operator<(const TThis &id) const
element_type & operator*(void) const
Dereference operator.
CSafeFlags operator|(const CSafeFlags &b) const
AutoArray< X, Del > & operator=(const AutoArray< X, Del > &p)
Assignment operator.
TThis operator-(const TThis &id) const
static ssize_t Sub(const void *first, const void *second)
calculate offset inside object
const first_type & first() const
bool IsNull(void) const
Check if the object is unassigned.
element_type * operator->(void) const
Reference operator.
CFastBuffer(size_t buf_size)
CNcbiActionGuard(const CNcbiActionGuard &)
void Execute(void) const override
X element_type
Define element type.
ERound
Whether to truncate/round a value.
TThis & operator=(const TThis &other)
static void * Add(void *object, ssize_t offset)
add offset to object reference (to get object's member)
element_type * x_Release(void) const
Release for const object.
unsigned int TSeqPos
Type for sequence locations and lengths.
void Swap(AutoPtr< X, Del > &a)
bool operator==(const TThis &id) const
bool operator<=(const TThis &id) const
CSafeFlags operator^(const CSafeFlags &b) const
constexpr size_t ArraySize(const Element(&)[Size])
CNullable(TValue value)
Initialize nullable with a specific value.
AutoArray(size_t size)
Construct the array using C++ new[] operator.
CStrictId< TKey, TStorage > TThis
size_t operator()(const ncbi::CStrictId< TKey, TStorage > &x) const
TType m_EmbeddedBuffer[KEmbeddedSize]
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
const element_type & operator[](size_t pos) const
Array style dereference (returns value)
ENormalizePath
Whether to normalize a path.
pair_base_member< deleter_type, bool > m_Data
State info.
bool s_ITERATE_SameObject(const Type &obj1, const Type &obj2)
CSafeFlags & operator^=(const CSafeFlags &b)
CNullable(ENull=null)
Create an empty nullable.
AutoArray(const AutoArray< X, Del > &p)
underlying_type< enum_type >::type storage_type
bool operator>=(const TThis &id) const
int TSignedSeqPos
Type for signed sequence position.
element_type * get(void) const
Get pointer.
AutoArray(element_type *p, const deleter_type &deleter)
static X * Create(void)
Default create function.
AutoPtr(element_type *p=0)
Constructor.
bool operator==(const CNullable< TValue, TNullToValue > &l, const CNullable< TValue, TNullToValue > &r)
enum ENcbiOwnership EOwnership
Ownership relations between objects.
const TType * begin(void) const
TValue & SetValue(void)
Get a non-const reference to the value.
static void Delete(X *object)
Array delete function.
EFollowLinks
Whether to follow symbolic links (also known as shortcuts or aliases)
TType operator[](size_t pos) const
CStrictId< SStrictId_Gi, SStrictId_Gi::TId > TGi
static void Delete(X *object)
Default delete function.
TType * operator+(size_t offset)
unique_ptr< T, TDeleter > make_c_unique(T *p, TDeleter d)
Eliminates the necessity for specifying types of both allocated resource and deallocating C function.
CStrictId(const TThis &other)
TThis operator+(const TThis &id) const
SStrictId_Tax::TId TTaxId
Taxon id type.
Del deleter_type
Alias for template argument.
AutoArray(element_type *p=0)
EInterruptOnSignal
Interrupt on signal mode.
CSafeFlags & operator&=(const CSafeFlags &b)
CNcbiIstream & operator>>(CNcbiIstream &in, CStrictId< TKey, TStorage > &id)
AutoPtr< X, Del > & operator=(element_type *p)
Assignment operator.
static void Delete(X *object)
C Language deallocation function.
bool operator==(int v) const
BEGIN_NCBI_NAMESPACE
NCBI_EOWNERSHIP_DEFINED.
#define DECLARE_OPERATOR_BOOL_PTR(Ptr)
Declaration of safe bool operator from pointer expression.
AutoPtr(element_type *p, const deleter_type &deleter)
Constructor.
CSafeFlags< E > operator&(E a, CSafeFlags< E > b)
CSafeFlags< E > operator^(E a, CSafeFlags< E > b)
AutoPtr(element_type *p, EOwnership ownership)
Constructor, own the pointed object if ownership == eTakeOwnership.
const TSeqPos kInvalidSeqPos
Define special value for invalid sequence position.
CNullable & operator=(TValue value)
Assign a value to the nullable.
ENullable
Whether a value is nullable.
element_type * get(void) const
Get pointer.
TThis operator-(void) const
list< unique_ptr< CAction_Base > > TActions
bool operator!=(int v) const
const second_type & second() const
constexpr CSafeFlags(enum_type flags)
void swap(NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair1, NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair2)
virtual void Execute(void) const =0
element_type * release(void)
Release will release ownership of pointer to caller.
ESign
Signedness of a value.
element_type * release(void)
Release will release ownership of pointer to caller.
bool operator!=(const TThis &id) const
void reset(element_type *p=0)
Reset will delete the old pointer, set content to the new value, and assume the ownership upon the ne...
bool operator>(const TThis &id) const
pair_base_member(const member_type &member_value)
const TValue & GetValue(void) const
Get a const reference to the current value.
const TType * end(void) const
AutoPtr(element_type *p, const deleter_type &deleter, EOwnership ownership)
Constructor, own the pointed object if ownership == eTakeOwnership.
@ eTriState_False
The value is equivalent to false/no.
@ eTriState_True
The value is equivalent to true/yes.
@ eTriState_Unknown
The value is indeterminate.
@ eRetriable_Unknown
It is unknown if the action can succeed if retried.
@ eRetriable_No
It makes no sense to retry the action.
@ eRetriable_Yes
It makes sense to try again.
@ eTrunc
Value must be truncated.
@ eRound
Value must be rounded.
@ eNormalizePath
Normalize a path.
@ eNotNormalizePath
Do not normalize a path.
@ eIgnoreLinks
Do not follow symbolic links.
@ eFollowLinks
Follow symbolic links.
@ eRestartOnSignal
Restart operation if interrupted by a signal.
@ eInterruptOnSignal
Cancel operation if interrupted by a signal.
@ eNotNullable
Value cannot be null.
@ eNullable
Value can be null.
@ eNegative
Value is negative.
@ ePositive
Value is positive.
@ eTakeOwnership
No ownership assumed.
#define ERR_POST(message)
Error posting with file, line number information but without error codes.
int32_t Int4
4-byte (32-bit) signed integer
uint32_t Uint4
4-byte (32-bit) unsigned integer
int64_t Int8
8-byte (64-bit) signed integer
uint64_t Uint8
8-byte (64-bit) unsigned integer
IO_PREFIX::ostream CNcbiOstream
Portable alias for ostream.
IO_PREFIX::istream CNcbiIstream
Portable alias for istream.
enum ENcbiOwnership EOwnership
Ownership relations between objects.
ENcbiOwnership
Ownership relations between objects.
#define NCBI_XNCBI_EXPORT
unsigned int
A callback function used to compare two keys in a database.
The blob sat and sat key Both must be positive integers</td > n< td > Non empty string The interpretation of the blob id depends on a processor Cassandra n processor expects the following format
const struct ncbi::grid::netcache::search::fields::SIZE size
Magic spell ;-) needed for some weird compilers... very empiric.
const GenericPointer< typename T::ValueType > T2 value
NCBI C++ auxiliary debug macros.
std::istream & in(std::istream &in_, double &x_)
double r(size_t dimension_, const Int4 *score_, const double *prob_, double theta_)
static SLJIT_INLINE sljit_ins l(sljit_gpr r, sljit_s32 d, sljit_gpr x, sljit_gpr b)
Functor template for deleting array of objects.
Functor template for the C language deallocation function, free().
Functor template for allocating object.
Functor template for deleting object.
Key structs must always be defined - they are used in aliasinfo.cpp.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4