BLPAPI C++ 3.26.6
Loading...
Searching...
No Matches
blpapi_correlationid.h
Go to the documentation of this file.
1/* Copyright 2012. Bloomberg Finance L.P.
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to
5 * deal in the Software without restriction, including without limitation the
6 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7 * sell copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions: The above
9 * copyright notice and this permission notice shall be included in all copies
10 * or substantial portions of the Software.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
17 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
18 * IN THE SOFTWARE.
19 */
20
37
38#ifndef INCLUDED_BLPAPI_CORRELATIONID
39#define INCLUDED_BLPAPI_CORRELATIONID
40
69
70#include <blpapi_call.h>
71#include <blpapi_defs.h>
72#include <blpapi_exception.h>
73#include <blpapi_types.h>
74
75#ifdef __cplusplus
76extern "C" {
77#endif
78
82
84
93struct blpapi_ManagedPtr_t_;
94typedef struct blpapi_ManagedPtr_t_
95 blpapi_ManagedPtr_t;
96
113typedef int (*blpapi_ManagedPtr_ManagerFunction_t)(
114 blpapi_ManagedPtr_t *managedPtr,
115 const blpapi_ManagedPtr_t *srcPtr,
116 int operation);
117
126typedef union {
127 int intValue;
128 void *ptr;
129} blpapi_ManagedPtr_t_data_;
130
138struct blpapi_ManagedPtr_t_ {
139 void *pointer;
140 blpapi_ManagedPtr_t_data_
141 userData[4];
142 blpapi_ManagedPtr_ManagerFunction_t
143 manager;
144};
145
154typedef struct blpapi_CorrelationId_t_ {
155 unsigned int size : 8;
156 unsigned int valueType
157 : 4;
158 unsigned int classId
159 : 16;
160 unsigned int internalClassId : 4;
161
162 union {
163 blpapi_UInt64_t intValue;
164 blpapi_ManagedPtr_t
165 ptrValue;
166 } value;
167} blpapi_CorrelationId_t;
168
185BLPAPI_EXPORT
186int blpapi_CorrelationId_managedPtrAddRef(
187 int *numRef, blpapi_CorrelationId_t *cid);
188
206BLPAPI_EXPORT
207int blpapi_CorrelationId_managedPtrRelease(
208 int *numRef, blpapi_CorrelationId_t *cid);
210
212
213#ifdef __cplusplus
214}
215
216#include <cstring>
217#include <ostream>
218#include <utility>
219
220namespace BloombergLP {
221namespace blpapi {
228
229// ===================
230// class CorrelationId
231// ===================
232
307
308 enum {
309 e_FOREIGN_OBJECT = BLPAPI_CORRELATION_INTERNAL_CLASS_FOREIGN_OBJECT
310 };
311
313 blpapi_CorrelationId_t d_impl;
314
315 void copy(const blpapi_CorrelationId_t& src, bool firstCopy);
316
317 template <typename TYPE>
318 static int managerFunc(blpapi_ManagedPtr_t *managedPtr,
319 const blpapi_ManagedPtr_t *srcPtr,
320 int operation);
322
323 template <typename TYPE> static void assertSmartPtrFits();
324
325 public:
326 // Possible return values for valueType() method.
327
329 UNSET_VALUE = BLPAPI_CORRELATION_TYPE_UNSET,
332 INT_VALUE = BLPAPI_CORRELATION_TYPE_INT,
335 POINTER_VALUE = BLPAPI_CORRELATION_TYPE_POINTER,
338 AUTOGEN_VALUE = BLPAPI_CORRELATION_TYPE_AUTOGEN
340 };
341
342 // The maximum value allowed for classId
343
344 enum {
345 MAX_CLASS_ID = BLPAPI_CORRELATION_MAX_CLASS_ID
347 };
348
356
358 explicit CorrelationId(const blpapi_CorrelationId_t& correlation);
363
364 CorrelationId(const CorrelationId& original);
369
370 explicit CorrelationId(long long value, int classId = 0);
376
377 explicit CorrelationId(void *value, int classId = 0);
383
384 template <typename TYPE>
385 CorrelationId(const TYPE& smartPtr, void *pointerValue, int classId = 0);
395
401
402 void swap(CorrelationId& other);
407
414
415 ValueType valueType() const;
419
420 unsigned short classId() const;
425
426 void *asPointer() const;
432
433 template <typename TYPE> TYPE asSmartPointer() const;
440
441 long long asInteger() const;
447
449 blpapi_CorrelationId_t& impl();
450 const blpapi_CorrelationId_t& impl() const;
452};
453
456
457// FREE OPERATORS
458inline bool operator==(const CorrelationId& lhs, const CorrelationId& rhs);
466
467inline bool operator!=(const CorrelationId& lhs, const CorrelationId& rhs);
471
472inline bool operator<(const CorrelationId& lhs, const CorrelationId& rhs);
482
483//=============================================================================
484// INLINE FUNCTION DEFINITIONS
485//=============================================================================
486
487// -------------------
488// class CorrelationId
489// -------------------
490
492{
493 std::memset(&d_impl, 0, sizeof(d_impl));
494}
495
498 const blpapi_CorrelationId_t& correlationId)
499{
500 copy(correlationId, /* firstCopy = */ true);
501}
503
505{
506 copy(original.d_impl, /* firstCopy = */ false);
507}
508
509inline CorrelationId::CorrelationId(long long intValue, int newClassId)
510{
511 std::memset(&d_impl, 0, sizeof(d_impl));
512
513 d_impl.size = static_cast<unsigned>(sizeof(d_impl));
514 d_impl.valueType = INT_VALUE;
515 d_impl.value.intValue = static_cast<blpapi_UInt64_t>(intValue);
516 d_impl.classId = static_cast<unsigned>(newClassId);
517}
518
519inline CorrelationId::CorrelationId(void *ptrValue, int newClassId)
520{
521 std::memset(&d_impl, 0, sizeof(d_impl));
522
523 d_impl.size = static_cast<unsigned>(sizeof(d_impl));
524 d_impl.valueType = POINTER_VALUE;
525 d_impl.value.ptrValue.pointer = ptrValue;
526 d_impl.classId = static_cast<unsigned>(newClassId);
527}
528
529template <typename TYPE>
531 const TYPE& smartPtr, void *ptrValue, int newClassId)
532{
533 // If you get a compiler error here, the specified smart pointer does not
534 // fit in the CorrelationId and cannot be used at this time.
535
536 assertSmartPtrFits<TYPE>();
537
538 std::memset(&d_impl, 0, sizeof(d_impl));
539
540 d_impl.size = sizeof(d_impl);
541 d_impl.valueType = POINTER_VALUE;
542 d_impl.classId = newClassId;
543
544 d_impl.value.ptrValue.pointer = ptrValue;
545 d_impl.value.ptrValue.manager = &CorrelationId::managerFunc<TYPE>;
546
547 void *arena = (void *)d_impl.value.ptrValue.userData;
548 new (arena) TYPE(smartPtr);
549}
550
552{
553 if (POINTER_VALUE == valueType()) {
554 blpapi_ManagedPtr_ManagerFunction_t& manager
555 = d_impl.value.ptrValue.manager;
556 if (manager) {
557 int numRef = 0;
558 if (d_impl.internalClassId == e_FOREIGN_OBJECT
559 && BLPAPI_CALL_AVAILABLE(
560 blpapi_CorrelationId_managedPtrRelease)
561 && BLPAPI_CALL_UNCHECKED(
562 blpapi_CorrelationId_managedPtrRelease)(
563 &numRef, &d_impl)
564 == 0
565 && numRef > 0) {
566 return;
567 }
568 manager(&d_impl.value.ptrValue, 0, BLPAPI_MANAGEDPTR_DESTROY);
569 }
570 }
571}
572
574{
575 using std::swap;
576
577 swap(other.d_impl, d_impl);
578}
579
581{
582 CorrelationId tmp(rhs);
583 tmp.swap(*this);
584 return *this;
585}
586
588inline blpapi_CorrelationId_t& CorrelationId::impl() { return d_impl; }
590
592{
593 return (ValueType)d_impl.valueType;
594}
595
596inline unsigned short CorrelationId::classId() const { return d_impl.classId; }
597
598inline void *CorrelationId::asPointer() const
599{
600 return d_impl.value.ptrValue.pointer;
601}
602
603template <typename TYPE> inline TYPE CorrelationId::asSmartPointer() const
604{
605 typedef int (*ManagerFuncPtr)(
606 blpapi_ManagedPtr_t *, const blpapi_ManagedPtr_t *, int);
607
608 ManagerFuncPtr managerFnPtr
609 = static_cast<ManagerFuncPtr>(&(CorrelationId::managerFunc<TYPE>));
610 if (d_impl.valueType != POINTER_VALUE
611 || (d_impl.value.ptrValue.manager != managerFnPtr)) {
612 return TYPE();
613 }
614 return *(TYPE *)d_impl.value.ptrValue.userData;
615}
616
617inline long long CorrelationId::asInteger() const
618{
619 return static_cast<long long>(d_impl.value.intValue);
620}
621
623inline const blpapi_CorrelationId_t& CorrelationId::impl() const
624{
625 return d_impl;
626}
628
630inline void CorrelationId::copy(
631 const blpapi_CorrelationId_t& src, bool firstCopy)
632{
633 d_impl = src;
634
635 if (POINTER_VALUE == valueType()) {
636 blpapi_ManagedPtr_ManagerFunction_t& manager
637 = d_impl.value.ptrValue.manager;
638 if (manager) {
639 if (d_impl.internalClassId == e_FOREIGN_OBJECT) {
640 if (firstCopy) {
641 // This CorrelationId is created from a C-handle, not from
642 // another C++ CorrelationId. But this C-handle can contain
643 // a pointer to a reference counter previously created in
644 // C++ layer. It is unsafe to reuse as it might be a
645 // dangling pointer by this time. Reset userData. This
646 // allows to create a new reference counter for new C++
647 // copies of this CorrelationId.
648 std::memset(&d_impl.value.ptrValue.userData,
649 0,
650 sizeof(d_impl.value.ptrValue.userData));
651 }
652 int numRef = 0;
654 BLPAPI_CALL(blpapi_CorrelationId_managedPtrAddRef)(
655 &numRef, &d_impl));
656 if (numRef > 1) {
657 return;
658 }
659 }
660 manager(&d_impl.value.ptrValue,
661 &src.value.ptrValue,
662 BLPAPI_MANAGEDPTR_COPY);
663 }
664 }
665}
667
669template <typename TYPE>
670inline int CorrelationId::managerFunc(blpapi_ManagedPtr_t *managedPtr,
671 const blpapi_ManagedPtr_t *srcPtr,
672 int operation)
673{
674 if (operation == BLPAPI_MANAGEDPTR_COPY) {
675 managedPtr->pointer = srcPtr->pointer;
676 managedPtr->manager = srcPtr->manager;
677
678 void *arena = managedPtr->userData;
679 new (arena) TYPE(*((TYPE *)&srcPtr->userData[0]));
680 } else if (operation == BLPAPI_MANAGEDPTR_DESTROY) {
681 TYPE *managedPtr_p = (TYPE *)&managedPtr->userData[0];
682 managedPtr_p->~TYPE();
683 } else if (operation == BLPAPI_MANAGEDPTR_IMPOSSIBLE_OPERATION) {
684 static int uniquePerTemplateInstantiation;
685
686 const int *address = &uniquePerTemplateInstantiation;
687 int rc = 0;
688 std::memcpy(&rc, &address, std::min(sizeof address, sizeof rc));
689 return rc;
690 // Instantiations of this function template, 'managerFunc<TYPE>',
691 // will never be called with 'operation' equal to
692 // 'BLPAPI_MANAGEDPTR_IMPOSSIBLE_OPERATION': this branch will never
693 // be executed.
694 //
695 // The observable use of the address of a local static variable
696 // forces '&managerFunc<T1> != &managerFunc<T2>' for types
697 // 'T1 != T2' even in the presence of Visual C++'s "identical
698 // COMDAT folding" optimization.
699 }
700
701 return 0;
702}
704
705template <typename TYPE> inline void CorrelationId::assertSmartPtrFits()
706{
707 if (false) {
708 // If you get a compiler error here, the specified smart pointer does
709 // not fit in the CorrelationId and cannot be used at this time.
710
711 char errorIfSmartPtrDoesNotFit[sizeof(TYPE) <= (sizeof(void *) * 4)
712 ? 1
713 : -1];
714 (void)errorIfSmartPtrDoesNotFit;
715 }
716}
717
718inline bool operator==(const CorrelationId& lhs, const CorrelationId& rhs)
719{
720 if (lhs.valueType() != rhs.valueType()) {
721 return false;
722 }
723 if (lhs.classId() != rhs.classId()) {
724 return false;
725 }
726 if (lhs.impl().internalClassId != rhs.impl().internalClassId) {
727 return false;
728 }
729
731 if (lhs.asPointer() != rhs.asPointer()) {
732 return false;
733 }
734 } else if (lhs.asInteger() != rhs.asInteger()) {
735 return false;
736 }
737
738 return true;
739}
740
741inline bool operator!=(const CorrelationId& lhs, const CorrelationId& rhs)
742{
743 return !(lhs == rhs);
744}
745
746inline bool operator<(const CorrelationId& lhs, const CorrelationId& rhs)
747{
749 && lhs.impl().internalClassId
750 == BLPAPI_CORRELATION_INTERNAL_CLASS_FOREIGN_OBJECT
752 && rhs.impl().internalClassId
753 == BLPAPI_CORRELATION_INTERNAL_CLASS_FOREIGN_OBJECT) {
754 return lhs.classId() == rhs.classId()
755 ? lhs.asPointer() < rhs.asPointer()
756 : lhs.classId() < rhs.classId();
757 }
758 return std::memcmp(&lhs.impl(), &rhs.impl(), sizeof(rhs.impl())) < 0;
759}
760
761inline std::ostream& operator<<(
762 std::ostream& os, const CorrelationId& correlator)
763{
764 const char *valueType = 0;
765 switch (correlator.valueType()) {
767 valueType = "UNSET";
768 break;
770 valueType = "INT";
771 break;
773 valueType = "POINTER";
774 break;
776 valueType = "AUTOGEN";
777 break;
778 default:
779 valueType = "UNKNOWN";
780 }
781
782 os << "[ valueType=" << valueType << " classId=" << correlator.classId()
783 << " internalClassId=" << correlator.impl().internalClassId
784 << " value=";
785
786 if (correlator.valueType() == CorrelationId::POINTER_VALUE) {
787 os << correlator.asPointer();
788 } else {
789 os << correlator.asInteger();
790 }
791 os << " ]";
792
793 return os;
794}
795
796} // close namespace blpapi
797} // close namespace BloombergLP
798
799#endif // #ifdef __cplusplus
800#endif // #ifndef INCLUDED_BLPAPI_CORRELATIONID
Provide functions for dispatchtbl.
Common definitions used by the library.
Defines Exceptions that can be thrown by the blpapi library.
Provide BLPAPI types.
Definition blpapi_correlationid.h:306
@ MAX_CLASS_ID
Definition blpapi_correlationid.h:345
void swap(CorrelationId &other)
Definition blpapi_correlationid.h:573
unsigned short classId() const
Definition blpapi_correlationid.h:596
ValueType valueType() const
Definition blpapi_correlationid.h:591
void * asPointer() const
Definition blpapi_correlationid.h:598
TYPE asSmartPointer() const
Definition blpapi_correlationid.h:603
~CorrelationId()
Definition blpapi_correlationid.h:551
CorrelationId()
Definition blpapi_correlationid.h:491
long long asInteger() const
Definition blpapi_correlationid.h:617
ValueType
Definition blpapi_correlationid.h:328
@ AUTOGEN_VALUE
The CorrelationId was created internally by API.
Definition blpapi_correlationid.h:338
@ UNSET_VALUE
Definition blpapi_correlationid.h:329
@ INT_VALUE
Definition blpapi_correlationid.h:332
@ POINTER_VALUE
Definition blpapi_correlationid.h:335
CorrelationId & operator=(const CorrelationId &rhs)
Definition blpapi_correlationid.h:580
static void throwOnError(int errorCode)
Definition blpapi_exception.h:556
Definition blpapi_abstractsession.h:452
bool operator==(const CorrelationId &lhs, const CorrelationId &rhs)
Definition blpapi_correlationid.h:718
std::ostream & operator<<(std::ostream &os, const CorrelationId &correlator)
Definition blpapi_correlationid.h:761
bool operator!=(const CorrelationId &lhs, const CorrelationId &rhs)
Definition blpapi_correlationid.h:741
bool operator<(const CorrelationId &lhs, const CorrelationId &rhs)
Definition blpapi_correlationid.h:746
Definition blpapi_abstractsession.h:451